diff --git a/src/chains.rs b/src/chains.rs index 0181cd3d099..a2485cab69f 100644 --- a/src/chains.rs +++ b/src/chains.rs @@ -195,12 +195,18 @@ pub fn rewrite_chain(expr: &ast::Expr, context: &RewriteContext, shape: Shape) - if fits_single_line { fits_single_line = match expr.node { ref e @ ast::ExprKind::MethodCall(..) => { - rewrite_method_call_with_overflow(e, - &mut last[0], - almost_total, - total_span, - context, - shape) + if rewrite_method_call_with_overflow(e, + &mut last[0], + almost_total, + total_span, + context, + 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'), } diff --git a/src/expr.rs b/src/expr.rs index 2723c4099c1..f282f7c0b57 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -172,9 +172,8 @@ fn format_expr(expr: &ast::Expr, ast::ExprKind::Mac(ref mac) => { // Failure to rewrite a marco should not imply failure to // rewrite the expression. - rewrite_macro(mac, None, context, shape, MacroPosition::Expression).or_else(|| { - wrap_str(context.snippet(expr.span), context.config.max_width, shape) - }) + rewrite_macro(mac, None, context, shape, MacroPosition::Expression) + .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(Some(ref expr)) => { @@ -576,14 +575,18 @@ fn rewrite_closure(capture: ast::CaptureBy, let block_threshold = context.config.closure_block_indent_threshold; 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 // means we must re-format. let block_shape = shape.block(); 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)))) } } @@ -1344,11 +1347,10 @@ impl Rewrite for ast::Arm { // 4 = ` => `.len() if shape.width > pat_width + comma.len() + 4 { let arm_shape = shape - .shrink_left(pat_width + 4) + .offset_left(pat_width + 4) .unwrap() .sub_width(comma.len()) - .unwrap() - .block(); + .unwrap(); let rewrite = nop_block_collapse(body.rewrite(context, arm_shape), arm_shape.width); let is_block = if let ast::ExprKind::Block(..) = body.node { true diff --git a/src/file_lines.rs b/src/file_lines.rs index e68751eb887..f11a0aaf6e2 100644 --- a/src/file_lines.rs +++ b/src/file_lines.rs @@ -194,9 +194,8 @@ impl JsonSpan { // To allow `collect()`ing into a `MultiMap`. fn into_tuple(self) -> Result<(String, Range), String> { let (lo, hi) = self.range; - let canonical = try!(canonicalize_path_string(&self.file).map_err(|_| { - format!("Can't canonicalize {}", &self.file) - })); + let canonical = try!(canonicalize_path_string(&self.file) + .map_err(|_| format!("Can't canonicalize {}", &self.file))); Ok((canonical, Range::new(lo, hi))) } } diff --git a/src/items.rs b/src/items.rs index 2cb4e46ecb5..1909b0d2679 100644 --- a/src/items.rs +++ b/src/items.rs @@ -1326,12 +1326,13 @@ pub fn rewrite_associated_type(ident: ast::Ident, let type_bounds_str = if let Some(ty_param_bounds) = ty_param_bounds_opt { let bounds: &[_] = ty_param_bounds; - let bound_str = try_opt!(bounds.iter() - .map(|ty_bound| { - ty_bound.rewrite(context, Shape::legacy(context.config.max_width, indent)) - }) - .intersperse(Some(" + ".to_string())) - .collect::>()); + let bound_str = try_opt!(bounds + .iter() + .map(|ty_bound| { + ty_bound.rewrite(context, Shape::legacy(context.config.max_width, indent)) + }) + .intersperse(Some(" + ".to_string())) + .collect::>()); if bounds.len() > 0 { format!(": {}", bound_str) } else { diff --git a/src/macros.rs b/src/macros.rs index fd5578e7f00..0bdc7eb60e0 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -146,12 +146,11 @@ pub fn rewrite_macro(mac: &ast::Mac, MacroStyle::Parens => { // Format macro invocation as function call, forcing no trailing // comma because not all macros support them. - rewrite_call(context, ¯o_name, &expr_vec, mac.span, shape, true).map(|rw| { - match position { - MacroPosition::Item => format!("{};", rw), - _ => rw, - } - }) + rewrite_call(context, ¯o_name, &expr_vec, mac.span, shape, true) + .map(|rw| match position { + MacroPosition::Item => format!("{};", rw), + _ => rw, + }) } MacroStyle::Brackets => { // Format macro invocation as array literal. diff --git a/src/types.rs b/src/types.rs index d766b9770de..0001b5637ab 100644 --- a/src/types.rs +++ b/src/types.rs @@ -587,31 +587,34 @@ impl Rewrite for ast::Ty { let mut_len = mut_str.len(); Some(match *lifetime { Some(ref lifetime) => { - let lt_budget = try_opt!(shape.width.checked_sub(2 + mut_len)); - let lt_str = try_opt!(lifetime.rewrite(context, - Shape::legacy(lt_budget, + let lt_budget = try_opt!(shape.width.checked_sub(2 + mut_len)); + let lt_str = try_opt!(lifetime.rewrite(context, + 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 + - 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 + mut_len + - lt_len)))) - } + mut_len + + lt_len)))) + } None => { - let budget = try_opt!(shape.width.checked_sub(1 + mut_len)); - format!("&{}{}", - mut_str, - try_opt!(mt.ty - .rewrite(context, - Shape::legacy(budget, - shape.indent + 1 + mut_len)))) - } + let budget = try_opt!(shape.width.checked_sub(1 + mut_len)); + format!("&{}{}", + mut_str, + try_opt!(mt.ty + .rewrite(context, + Shape::legacy(budget, + shape.indent + 1 + + mut_len)))) + } }) } // FIXME: we drop any comments here, even though it's a silly place to put diff --git a/tests/source/match.rs b/tests/source/match.rs index 2fb584c322c..43b0b033ea6 100644 --- a/tests/source/match.rs +++ b/tests/source/match.rs @@ -295,3 +295,81 @@ fn guards() { (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, ReadError> = nodeset + .iter() + .map(|node| { + XPathNodeReader::new(node, &context).and_then(|r| ArtistRef::from_xml(&r)) + }) + .collect(); + res? + } + _ => Vec::new(), + }, + }) +} diff --git a/tests/target/match.rs b/tests/target/match.rs index 75156347978..0da943d28f7 100644 --- a/tests/target/match.rs +++ b/tests/target/match.rs @@ -310,3 +310,82 @@ fn guards() { 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, ReadError> = nodeset + .iter() + .map(|node| { + XPathNodeReader::new(node, &context) + .and_then(|r| ArtistRef::from_xml(&r)) + }) + .collect(); + res? + } + _ => Vec::new(), + }, + }) +}