1
Fork 0

Merge pull request #1454 from topecongiro/match

Format nested mathces properly.
This commit is contained in:
Nick Cameron 2017-05-02 10:40:31 +12:00 committed by GitHub
commit c546f1b396
8 changed files with 219 additions and 52 deletions

View file

@ -200,12 +200,18 @@ pub fn rewrite_chain(expr: &ast::Expr, context: &RewriteContext, shape: Shape) -
if fits_single_line { if fits_single_line {
fits_single_line = match expr.node { fits_single_line = match expr.node {
ref e @ ast::ExprKind::MethodCall(..) => { ref e @ ast::ExprKind::MethodCall(..) => {
rewrite_method_call_with_overflow(e, if rewrite_method_call_with_overflow(e,
&mut last[0], &mut last[0],
almost_total, almost_total,
total_span, total_span,
context, context,
shape) shape) {
// If the first line of the last method does not fit into a single line
// after the others, allow new lines.
almost_total + first_line_width(&last[0]) < context.config.max_width
} else {
false
}
} }
_ => !last[0].contains('\n'), _ => !last[0].contains('\n'),
} }

View file

@ -176,9 +176,8 @@ fn format_expr(expr: &ast::Expr,
ast::ExprKind::Mac(ref mac) => { ast::ExprKind::Mac(ref mac) => {
// Failure to rewrite a marco should not imply failure to // Failure to rewrite a marco should not imply failure to
// rewrite the expression. // rewrite the expression.
rewrite_macro(mac, None, context, shape, MacroPosition::Expression).or_else(|| { rewrite_macro(mac, None, context, shape, MacroPosition::Expression)
wrap_str(context.snippet(expr.span), context.config.max_width, shape) .or_else(|| wrap_str(context.snippet(expr.span), context.config.max_width, shape))
})
} }
ast::ExprKind::Ret(None) => wrap_str("return".to_owned(), context.config.max_width, shape), ast::ExprKind::Ret(None) => wrap_str("return".to_owned(), context.config.max_width, shape),
ast::ExprKind::Ret(Some(ref expr)) => { ast::ExprKind::Ret(Some(ref expr)) => {
@ -582,14 +581,18 @@ fn rewrite_closure(capture: ast::CaptureBy,
let block_threshold = context.config.closure_block_indent_threshold; let block_threshold = context.config.closure_block_indent_threshold;
if block_threshold < 0 || rewrite.matches('\n').count() <= block_threshold as usize { if block_threshold < 0 || rewrite.matches('\n').count() <= block_threshold as usize {
return Some(format!("{} {}", prefix, rewrite)); if let Some(rewrite) = wrap_str(rewrite, context.config.max_width, shape) {
return Some(format!("{} {}", prefix, rewrite));
}
} }
// The body of the closure is big enough to be block indented, that // The body of the closure is big enough to be block indented, that
// means we must re-format. // means we must re-format.
let block_shape = shape.block(); let block_shape = shape.block();
let rewrite = try_opt!(block.rewrite(&context, block_shape)); let rewrite = try_opt!(block.rewrite(&context, block_shape));
Some(format!("{} {}", prefix, rewrite)) Some(format!("{} {}",
prefix,
try_opt!(wrap_str(rewrite, block_shape.width, block_shape))))
} }
} }
@ -1341,11 +1344,10 @@ impl Rewrite for ast::Arm {
// 4 = ` => `.len() // 4 = ` => `.len()
if shape.width > pat_width + comma.len() + 4 { if shape.width > pat_width + comma.len() + 4 {
let arm_shape = shape let arm_shape = shape
.shrink_left(pat_width + 4) .offset_left(pat_width + 4)
.unwrap() .unwrap()
.sub_width(comma.len()) .sub_width(comma.len())
.unwrap() .unwrap();
.block();
let rewrite = nop_block_collapse(body.rewrite(context, arm_shape), arm_shape.width); let rewrite = nop_block_collapse(body.rewrite(context, arm_shape), arm_shape.width);
let is_block = if let ast::ExprKind::Block(..) = body.node { let is_block = if let ast::ExprKind::Block(..) = body.node {
true true

View file

@ -194,9 +194,8 @@ impl JsonSpan {
// To allow `collect()`ing into a `MultiMap`. // To allow `collect()`ing into a `MultiMap`.
fn into_tuple(self) -> Result<(String, Range), String> { fn into_tuple(self) -> Result<(String, Range), String> {
let (lo, hi) = self.range; let (lo, hi) = self.range;
let canonical = try!(canonicalize_path_string(&self.file).map_err(|_| { let canonical = try!(canonicalize_path_string(&self.file)
format!("Can't canonicalize {}", &self.file) .map_err(|_| format!("Can't canonicalize {}", &self.file)));
}));
Ok((canonical, Range::new(lo, hi))) Ok((canonical, Range::new(lo, hi)))
} }
} }

View file

@ -1300,12 +1300,13 @@ pub fn rewrite_associated_type(ident: ast::Ident,
let type_bounds_str = if let Some(ty_param_bounds) = ty_param_bounds_opt { let type_bounds_str = if let Some(ty_param_bounds) = ty_param_bounds_opt {
let bounds: &[_] = ty_param_bounds; let bounds: &[_] = ty_param_bounds;
let bound_str = try_opt!(bounds.iter() let bound_str = try_opt!(bounds
.map(|ty_bound| { .iter()
ty_bound.rewrite(context, Shape::legacy(context.config.max_width, indent)) .map(|ty_bound| {
}) ty_bound.rewrite(context, Shape::legacy(context.config.max_width, indent))
.intersperse(Some(" + ".to_string())) })
.collect::<Option<String>>()); .intersperse(Some(" + ".to_string()))
.collect::<Option<String>>());
if bounds.len() > 0 { if bounds.len() > 0 {
format!(": {}", bound_str) format!(": {}", bound_str)
} else { } else {

View file

@ -146,12 +146,11 @@ pub fn rewrite_macro(mac: &ast::Mac,
MacroStyle::Parens => { MacroStyle::Parens => {
// Format macro invocation as function call, forcing no trailing // Format macro invocation as function call, forcing no trailing
// comma because not all macros support them. // comma because not all macros support them.
rewrite_call(context, &macro_name, &expr_vec, mac.span, shape, true).map(|rw| { rewrite_call(context, &macro_name, &expr_vec, mac.span, shape, true)
match position { .map(|rw| match position {
MacroPosition::Item => format!("{};", rw), MacroPosition::Item => format!("{};", rw),
_ => rw, _ => rw,
} })
})
} }
MacroStyle::Brackets => { MacroStyle::Brackets => {
// Format macro invocation as array literal. // Format macro invocation as array literal.

View file

@ -587,31 +587,34 @@ impl Rewrite for ast::Ty {
let mut_len = mut_str.len(); let mut_len = mut_str.len();
Some(match *lifetime { Some(match *lifetime {
Some(ref lifetime) => { Some(ref lifetime) => {
let lt_budget = try_opt!(shape.width.checked_sub(2 + mut_len)); let lt_budget = try_opt!(shape.width.checked_sub(2 + mut_len));
let lt_str = try_opt!(lifetime.rewrite(context, let lt_str = try_opt!(lifetime.rewrite(context,
Shape::legacy(lt_budget, Shape::legacy(lt_budget,
shape.indent +
2 +
mut_len)));
let lt_len = lt_str.len();
let budget = try_opt!(shape.width.checked_sub(2 + mut_len + lt_len));
format!("&{} {}{}",
lt_str,
mut_str,
try_opt!(mt.ty
.rewrite(context,
Shape::legacy(budget,
shape.indent + 2 + shape.indent + 2 +
mut_len))); mut_len +
let lt_len = lt_str.len(); lt_len))))
let budget = try_opt!(shape.width.checked_sub(2 + mut_len + lt_len)); }
format!("&{} {}{}",
lt_str,
mut_str,
try_opt!(mt.ty
.rewrite(context,
Shape::legacy(budget,
shape.indent + 2 + mut_len +
lt_len))))
}
None => { None => {
let budget = try_opt!(shape.width.checked_sub(1 + mut_len)); let budget = try_opt!(shape.width.checked_sub(1 + mut_len));
format!("&{}{}", format!("&{}{}",
mut_str, mut_str,
try_opt!(mt.ty try_opt!(mt.ty
.rewrite(context, .rewrite(context,
Shape::legacy(budget, Shape::legacy(budget,
shape.indent + 1 + mut_len)))) shape.indent + 1 +
} mut_len))))
}
}) })
} }
// FIXME: we drop any comments here, even though it's a silly place to put // FIXME: we drop any comments here, even though it's a silly place to put

View file

@ -295,3 +295,81 @@ fn guards() {
(bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb || cccccccccccccccccccccccccccccccccccccccc) => {} (bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb || cccccccccccccccccccccccccccccccccccccccc) => {}
} }
} }
fn issue1371() {
Some(match type_ {
sfEvtClosed => Closed,
sfEvtResized => {
let e = unsafe { *event.size.as_ref() };
Resized {
width: e.width,
height: e.height,
}
}
sfEvtLostFocus => LostFocus,
sfEvtGainedFocus => GainedFocus,
sfEvtTextEntered => {
TextEntered {
unicode: unsafe {
::std::char::from_u32((*event.text.as_ref()).unicode)
.expect("Invalid unicode encountered on TextEntered event")
},
}
}
sfEvtKeyPressed => {
let e = unsafe { event.key.as_ref() };
KeyPressed {
code: unsafe { ::std::mem::transmute(e.code) },
alt: e.alt.to_bool(),
ctrl: e.control.to_bool(),
shift: e.shift.to_bool(),
system: e.system.to_bool(),
}
}
sfEvtKeyReleased => {
let e = unsafe { event.key.as_ref() };
KeyReleased {
code: unsafe { ::std::mem::transmute(e.code) },
alt: e.alt.to_bool(),
ctrl: e.control.to_bool(),
shift: e.shift.to_bool(),
system: e.system.to_bool(),
}
}
})
}
fn issue1395() {
let bar = Some(true);
let foo = Some(true);
let mut x = false;
bar.and_then(|_| {
match foo {
None => None,
Some(b) => {
x = true;
Some(b)
}
}
});
}
fn issue1456() {
Ok(Recording {
artists: match reader.evaluate(".//mb:recording/mb:artist-credit/mb:name-credit")? {
Nodeset(nodeset) => {
let res: Result<Vec<ArtistRef>, ReadError> = nodeset
.iter()
.map(|node| {
XPathNodeReader::new(node, &context).and_then(|r| ArtistRef::from_xml(&r))
})
.collect();
res?
}
_ => Vec::new(),
},
})
}

View file

@ -310,3 +310,82 @@ fn guards() {
cccccccccccccccccccccccccccccccccccccccc) => {} cccccccccccccccccccccccccccccccccccccccc) => {}
} }
} }
fn issue1371() {
Some(match type_ {
sfEvtClosed => Closed,
sfEvtResized => {
let e = unsafe { *event.size.as_ref() };
Resized {
width: e.width,
height: e.height,
}
}
sfEvtLostFocus => LostFocus,
sfEvtGainedFocus => GainedFocus,
sfEvtTextEntered => {
TextEntered {
unicode:
unsafe {
::std::char::from_u32((*event.text.as_ref()).unicode)
.expect("Invalid unicode encountered on TextEntered event")
},
}
}
sfEvtKeyPressed => {
let e = unsafe { event.key.as_ref() };
KeyPressed {
code: unsafe { ::std::mem::transmute(e.code) },
alt: e.alt.to_bool(),
ctrl: e.control.to_bool(),
shift: e.shift.to_bool(),
system: e.system.to_bool(),
}
}
sfEvtKeyReleased => {
let e = unsafe { event.key.as_ref() };
KeyReleased {
code: unsafe { ::std::mem::transmute(e.code) },
alt: e.alt.to_bool(),
ctrl: e.control.to_bool(),
shift: e.shift.to_bool(),
system: e.system.to_bool(),
}
}
})
}
fn issue1395() {
let bar = Some(true);
let foo = Some(true);
let mut x = false;
bar.and_then(|_| match foo {
None => None,
Some(b) => {
x = true;
Some(b)
}
});
}
fn issue1456() {
Ok(Recording {
artists: match reader
.evaluate(".//mb:recording/mb:artist-credit/mb:name-credit")? {
Nodeset(nodeset) => {
let res: Result<Vec<ArtistRef>, ReadError> = nodeset
.iter()
.map(|node| {
XPathNodeReader::new(node, &context)
.and_then(|r| ArtistRef::from_xml(&r))
})
.collect();
res?
}
_ => Vec::new(),
},
})
}