]> git.lizzy.rs Git - rust.git/blobdiff - src/expr.rs
Use rewrite() instead of format_expr
[rust.git] / src / expr.rs
index 7953c344b40c029341a94caaa49e9f33b763dba2..228722474e1b8706d6aead24912a92b87367c41f 100644 (file)
 use chains::rewrite_chain;
 use codemap::{LineRangeUtils, SpanUtils};
 use comment::{combine_strs_with_missing_comments, contains_comment, recover_comment_removed,
-              rewrite_comment, FindUncommented};
+              rewrite_comment, rewrite_missing_comment, FindUncommented};
 use config::{Config, ControlBraceStyle, IndentStyle, MultilineStyle, Style};
 use items::{span_hi_for_arg, span_lo_for_arg};
 use lists::{definitive_tactic, itemize_list, shape_for_tactic, struct_lit_formatting,
             struct_lit_shape, struct_lit_tactic, write_list, DefinitiveListTactic, ListFormatting,
-            ListItem, ListTactic, Separator, SeparatorTactic};
-use macros::{rewrite_macro, MacroPosition};
+            ListItem, ListTactic, Separator, SeparatorPlace, SeparatorTactic};
+use macros::{rewrite_macro, MacroArg, MacroPosition};
 use patterns::{can_be_overflowed_pat, TuplePatField};
 use rewrite::{Rewrite, RewriteContext};
 use string::{rewrite_string, StringFormat};
@@ -44,7 +44,7 @@ fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
     }
 }
 
-#[derive(PartialEq)]
+#[derive(Copy, Clone, PartialEq)]
 pub enum ExprType {
     Statement,
     SubExpression,
@@ -65,7 +65,7 @@ pub fn format_expr(
     let expr_rw = match expr.node {
         ast::ExprKind::Array(ref expr_vec) => rewrite_array(
             expr_vec.iter().map(|e| &**e),
-            mk_sp(context.codemap.span_after(expr.span, "["), expr.span.hi),
+            mk_sp(context.codemap.span_after(expr.span, "["), expr.span.hi()),
             context,
             shape,
             false,
@@ -81,7 +81,7 @@ pub fn format_expr(
             ),
         },
         ast::ExprKind::Call(ref callee, ref args) => {
-            let inner_span = mk_sp(callee.span.hi, expr.span.hi);
+            let inner_span = mk_sp(callee.span.hi(), expr.span.hi());
             rewrite_call_with_binary_search(
                 context,
                 &**callee,
@@ -130,11 +130,10 @@ pub fn format_expr(
                 ExprType::Statement => {
                     if is_unsafe_block(block) {
                         block.rewrite(context, shape)
-                    } else {
+                    } else if let rw @ Some(_) = rewrite_empty_block(context, block, shape) {
                         // Rewrite block without trying to put it in a single line.
-                        if let rw @ Some(_) = rewrite_empty_block(context, block, shape) {
-                            return rw;
-                        }
+                        rw
+                    } else {
                         let prefix = try_opt!(block_prefix(context, block, shape));
                         rewrite_block_with_visitor(context, &prefix, block, shape)
                     }
@@ -181,6 +180,11 @@ pub fn format_expr(
                 )
             }
         }
+        ast::ExprKind::Yield(ref opt_expr) => if let Some(ref expr) = *opt_expr {
+            rewrite_unary_prefix(context, "yield ", &**expr, shape)
+        } else {
+            wrap_str("yield".to_string(), context.config.max_width(), shape)
+        },
         ast::ExprKind::Closure(capture, ref fn_decl, ref body, _) => {
             rewrite_closure(capture, fn_decl, body, expr.span, context, shape)
         }
@@ -245,7 +249,7 @@ fn needs_space_before_range(context: &RewriteContext, lhs: &ast::Expr) -> bool {
             }
 
             match (lhs.as_ref().map(|x| &**x), rhs.as_ref().map(|x| &**x)) {
-                (Some(ref lhs), Some(ref rhs)) => {
+                (Some(lhs), Some(rhs)) => {
                     let sp_delim = if context.config.spaces_around_ranges() {
                         format!(" {} ", delim)
                     } else if needs_space_before_range(context, lhs) {
@@ -253,23 +257,23 @@ fn needs_space_before_range(context: &RewriteContext, lhs: &ast::Expr) -> bool {
                     } else {
                         delim.into()
                     };
-                    rewrite_pair(&**lhs, &**rhs, "", &sp_delim, "", context, shape)
+                    rewrite_pair(&*lhs, &*rhs, "", &sp_delim, "", context, shape)
                 }
-                (None, Some(ref rhs)) => {
+                (None, Some(rhs)) => {
                     let sp_delim = if context.config.spaces_around_ranges() {
                         format!("{} ", delim)
                     } else {
                         delim.into()
                     };
-                    rewrite_unary_prefix(context, &sp_delim, &**rhs, shape)
+                    rewrite_unary_prefix(context, &sp_delim, &*rhs, shape)
                 }
-                (Some(ref lhs), None) => {
+                (Some(lhs), None) => {
                     let sp_delim = if context.config.spaces_around_ranges() {
                         format!(" {}", delim)
                     } else {
                         delim.into()
                     };
-                    rewrite_unary_suffix(context, &sp_delim, &**lhs, shape)
+                    rewrite_unary_suffix(context, &sp_delim, &*lhs, shape)
                 }
                 (None, None) => wrap_str(delim.into(), context.config.max_width(), shape),
             }
@@ -282,17 +286,17 @@ fn needs_space_before_range(context: &RewriteContext, lhs: &ast::Expr) -> bool {
             shape,
         ),
         ast::ExprKind::Catch(ref block) => {
-            if let rewrite @ Some(_) = rewrite_single_line_block(context, "do catch ", block, shape)
-            {
-                return rewrite;
+            if let rw @ Some(_) = rewrite_single_line_block(context, "do catch ", block, shape) {
+                rw
+            } else {
+                // 9 = `do catch `
+                let budget = shape.width.checked_sub(9).unwrap_or(0);
+                Some(format!(
+                    "{}{}",
+                    "do catch ",
+                    try_opt!(block.rewrite(&context, Shape::legacy(budget, shape.indent)))
+                ))
             }
-            // 9 = `do catch `
-            let budget = shape.width.checked_sub(9).unwrap_or(0);
-            Some(format!(
-                "{}{}",
-                "do catch ",
-                try_opt!(block.rewrite(&context, Shape::legacy(budget, shape.indent)))
-            ))
         }
     };
 
@@ -304,8 +308,8 @@ fn needs_space_before_range(context: &RewriteContext, lhs: &ast::Expr) -> bool {
             let attrs = outer_attributes(&expr.attrs);
             let attrs_str = try_opt!(attrs.rewrite(context, shape));
             let span = mk_sp(
-                attrs.last().map_or(expr.span.lo, |attr| attr.span.hi),
-                expr.span.lo,
+                attrs.last().map_or(expr.span.lo(), |attr| attr.span.hi()),
+                expr.span.lo(),
             );
             combine_strs_with_missing_comments(context, &attrs_str, &expr_str, span, shape, false)
         })
@@ -413,11 +417,11 @@ pub fn rewrite_array<'a, I>(
         context.codemap,
         expr_iter,
         "]",
-        |item| item.span.lo,
-        |item| item.span.hi,
+        |item| item.span.lo(),
+        |item| item.span.hi(),
         |item| item.rewrite(context, nested_shape),
-        span.lo,
-        span.hi,
+        span.lo(),
+        span.hi(),
         false,
     ).collect::<Vec<_>>();
 
@@ -473,6 +477,7 @@ pub fn rewrite_array<'a, I>(
         } else {
             SeparatorTactic::Vertical
         },
+        separator_place: SeparatorPlace::Back,
         shape: nested_shape,
         ends_with_newline: ends_with_newline,
         preserve_newline: false,
@@ -483,7 +488,7 @@ pub fn rewrite_array<'a, I>(
     let result = if context.config.array_layout() == IndentStyle::Visual ||
         tactic == DefinitiveListTactic::Horizontal
     {
-        if context.config.spaces_within_square_brackets() && list_str.len() > 0 {
+        if context.config.spaces_within_square_brackets() && !list_str.is_empty() {
             format!("[ {} ]", list_str)
         } else {
             format!("[{}]", list_str)
@@ -531,7 +536,7 @@ fn rewrite_closure_fn_decl(
         |arg| span_hi_for_arg(context, arg),
         |arg| arg.rewrite(context, arg_shape),
         context.codemap.span_after(span, "|"),
-        body.span.lo,
+        body.span.lo(),
         false,
     );
     let item_vec = arg_items.collect::<Vec<_>>();
@@ -555,6 +560,7 @@ fn rewrite_closure_fn_decl(
         tactic: tactic,
         separator: ",",
         trailing_separator: SeparatorTactic::Never,
+        separator_place: SeparatorPlace::Back,
         shape: arg_shape,
         ends_with_newline: false,
         preserve_newline: true,
@@ -625,7 +631,7 @@ fn rewrite_closure(
         };
         if no_return_type && !needs_block {
             // lock.stmts.len() == 1
-            if let Some(ref expr) = stmt_expr(&block.stmts[0]) {
+            if let Some(expr) = stmt_expr(&block.stmts[0]) {
                 if let Some(rw) = rewrite_closure_expr(expr, &prefix, context, body_shape) {
                     return Some(rw);
                 }
@@ -645,7 +651,7 @@ fn rewrite_closure(
         }
 
         // Either we require a block, or tried without and failed.
-        rewrite_closure_block(&block, &prefix, context, body_shape)
+        rewrite_closure_block(block, &prefix, context, body_shape)
     } else {
         rewrite_closure_expr(body, &prefix, context, body_shape).or_else(|| {
             // The closure originally had a non-block expression, but we can't fit on
@@ -688,6 +694,13 @@ fn rewrite_closure_expr(
     if classify::expr_requires_semi_to_be_stmt(left_most_sub_expr(expr)) {
         rewrite = and_one_line(rewrite);
     }
+    rewrite = rewrite.and_then(|rw| {
+        if context.config.multiline_closure_forces_block() && rw.contains('\n') {
+            None
+        } else {
+            Some(rw)
+        }
+    });
     rewrite.map(|rw| format!("{} {}", prefix, rw))
 }
 
@@ -702,7 +715,7 @@ fn rewrite_closure_block(
     // closure is large.
     let block_threshold = context.config.closure_block_indent_threshold();
     if block_threshold >= 0 {
-        if let Some(block_str) = block.rewrite(&context, shape) {
+        if let Some(block_str) = block.rewrite(context, shape) {
             if block_str.matches('\n').count() <= block_threshold as usize &&
                 !need_block_indent(&block_str, shape)
             {
@@ -716,7 +729,7 @@ fn rewrite_closure_block(
     // The body of the closure is big enough to be block indented, that
     // means we must re-format.
     let block_shape = shape.block();
-    let block_str = try_opt!(block.rewrite(&context, block_shape));
+    let block_str = try_opt!(block.rewrite(context, block_shape));
     Some(format!("{} {}", prefix, block_str))
 }
 
@@ -824,9 +837,9 @@ fn rewrite_block_with_visitor(
         ast::BlockCheckMode::Unsafe(..) => {
             let snippet = context.snippet(block.span);
             let open_pos = try_opt!(snippet.find_uncommented("{"));
-            visitor.last_pos = block.span.lo + BytePos(open_pos as u32)
+            visitor.last_pos = block.span.lo() + BytePos(open_pos as u32)
         }
-        ast::BlockCheckMode::Default => visitor.last_pos = block.span.lo,
+        ast::BlockCheckMode::Default => visitor.last_pos = block.span.lo(),
     }
 
     visitor.visit_block(block, None);
@@ -863,16 +876,8 @@ fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
                     ""
                 };
 
-                format_expr(
-                    ex,
-                    match self.node {
-                        ast::StmtKind::Expr(_) => ExprType::SubExpression,
-                        ast::StmtKind::Semi(_) => ExprType::Statement,
-                        _ => unreachable!(),
-                    },
-                    context,
-                    try_opt!(shape.sub_width(suffix.len())),
-                ).map(|s| s + suffix)
+                let shape = try_opt!(shape.sub_width(suffix.len()));
+                format_expr(ex, ExprType::Statement, context, shape).map(|s| s + suffix)
             }
             ast::StmtKind::Mac(..) | ast::StmtKind::Item(..) => None,
         };
@@ -1183,15 +1188,19 @@ fn rewrite_cond(
         let cond_span = if let Some(cond) = self.cond {
             cond.span
         } else {
-            mk_sp(self.block.span.lo, self.block.span.lo)
+            mk_sp(self.block.span.lo(), self.block.span.lo())
         };
 
-        // for event in event
+        // `for event in event`
+        // Do not include label in the span.
+        let lo = self.label.map_or(self.span.lo(), |label| label.span.hi());
         let between_kwd_cond = mk_sp(
-            context.codemap.span_after(self.span, self.keyword.trim()),
+            context
+                .codemap
+                .span_after(mk_sp(lo, self.span.hi()), self.keyword.trim()),
             self.pat
-                .map_or(cond_span.lo, |p| if self.matcher.is_empty() {
-                    p.span.lo
+                .map_or(cond_span.lo(), |p| if self.matcher.is_empty() {
+                    p.span.lo()
                 } else {
                     context.codemap.span_before(self.span, self.matcher.trim())
                 }),
@@ -1200,7 +1209,7 @@ fn rewrite_cond(
         let between_kwd_cond_comment = extract_comment(between_kwd_cond, context, shape);
 
         let after_cond_comment =
-            extract_comment(mk_sp(cond_span.hi, self.block.span.lo), context, shape);
+            extract_comment(mk_sp(cond_span.hi(), self.block.span.lo()), context, shape);
 
         let block_sep = if self.cond.is_none() && between_kwd_cond_comment.is_some() {
             ""
@@ -1291,7 +1300,7 @@ fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
                         next_else_block.as_ref().map(|e| &**e),
                         false,
                         true,
-                        mk_sp(else_block.span.lo, self.span.hi),
+                        mk_sp(else_block.span.lo(), self.span.hi()),
                     ).rewrite(context, shape)
                 }
                 ast::ExprKind::If(ref cond, ref if_block, ref next_else_block) => {
@@ -1302,7 +1311,7 @@ fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
                         next_else_block.as_ref().map(|e| &**e),
                         false,
                         true,
-                        mk_sp(else_block.span.lo, self.span.hi),
+                        mk_sp(else_block.span.lo(), self.span.hi()),
                     ).rewrite(context, shape)
                 }
                 _ => {
@@ -1318,10 +1327,10 @@ fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
             };
 
             let between_kwd_else_block = mk_sp(
-                self.block.span.hi,
+                self.block.span.hi(),
                 context
                     .codemap
-                    .span_before(mk_sp(self.block.span.hi, else_block.span.lo), "else"),
+                    .span_before(mk_sp(self.block.span.hi(), else_block.span.lo()), "else"),
             );
             let between_kwd_else_block_comment =
                 extract_comment(between_kwd_else_block, context, shape);
@@ -1329,8 +1338,8 @@ fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
             let after_else = mk_sp(
                 context
                     .codemap
-                    .span_after(mk_sp(self.block.span.hi, else_block.span.lo), "else"),
-                else_block.span.lo,
+                    .span_after(mk_sp(self.block.span.hi(), else_block.span.lo()), "else"),
+                else_block.span.lo(),
             );
             let after_else_comment = extract_comment(after_else, context, shape);
 
@@ -1369,21 +1378,13 @@ fn rewrite_label(label: Option<ast::SpannedIdent>) -> String {
 }
 
 fn extract_comment(span: Span, context: &RewriteContext, shape: Shape) -> Option<String> {
-    let comment_str = context.snippet(span);
-    if contains_comment(&comment_str) {
-        let comment = try_opt!(rewrite_comment(
-            comment_str.trim(),
-            false,
-            shape,
-            context.config,
-        ));
-        Some(format!(
+    match rewrite_missing_comment(span, shape, context) {
+        Some(ref comment) if !comment.is_empty() => Some(format!(
             "\n{indent}{}\n{indent}",
             comment,
             indent = shape.indent.to_string(context.config)
-        ))
-    } else {
-        None
+        )),
+        _ => None,
     }
 }
 
@@ -1498,9 +1499,9 @@ fn rewrite_match(
     let open_brace_pos = if inner_attrs.is_empty() {
         context
             .codemap
-            .span_after(mk_sp(cond.span.hi, arms[0].span().lo), "{")
+            .span_after(mk_sp(cond.span.hi(), arms[0].span().lo()), "{")
     } else {
-        inner_attrs[inner_attrs.len() - 1].span().hi
+        inner_attrs[inner_attrs.len() - 1].span().hi()
     };
 
     let arm_indent_str = if context.config.indent_match_arms() {
@@ -1565,11 +1566,11 @@ fn rewrite_match_arms(
             .zip(is_last_iter)
             .map(|(arm, is_last)| ArmWrapper::new(arm, is_last)),
         "}",
-        |arm| arm.arm.span().lo,
-        |arm| arm.arm.span().hi,
+        |arm| arm.arm.span().lo(),
+        |arm| arm.arm.span().hi(),
         |arm| arm.rewrite(context, arm_shape),
         open_brace_pos,
-        span.hi,
+        span.hi(),
         false,
     );
     let arms_vec: Vec<_> = items.collect();
@@ -1578,6 +1579,7 @@ fn rewrite_match_arms(
         // We will add/remove commas inside `arm.rewrite()`, and hence no separator here.
         separator: "",
         trailing_separator: SeparatorTactic::Never,
+        separator_place: SeparatorPlace::Back,
         shape: arm_shape,
         ends_with_newline: true,
         preserve_newline: true,
@@ -1604,11 +1606,14 @@ fn rewrite_match_arm(
             ));
         }
         (
-            mk_sp(arm.attrs[arm.attrs.len() - 1].span.hi, arm.pats[0].span.lo),
+            mk_sp(
+                arm.attrs[arm.attrs.len() - 1].span.hi(),
+                arm.pats[0].span.lo(),
+            ),
             try_opt!(arm.attrs.rewrite(context, shape)),
         )
     } else {
-        (mk_sp(arm.span().lo, arm.span().lo), String::new())
+        (mk_sp(arm.span().lo(), arm.span().lo()), String::new())
     };
     let pats_str = try_opt!(
         rewrite_match_pattern(context, &arm.pats, &arm.guard, shape).and_then(|pats_str| {
@@ -1634,7 +1639,7 @@ fn rewrite_match_arm(
 
 fn rewrite_match_pattern(
     context: &RewriteContext,
-    pats: &Vec<ptr::P<ast::Pat>>,
+    pats: &[ptr::P<ast::Pat>],
     guard: &Option<ptr::P<ast::Expr>>,
     shape: Shape,
 ) -> Option<String> {
@@ -1659,6 +1664,7 @@ fn rewrite_match_pattern(
         tactic: tactic,
         separator: " |",
         trailing_separator: SeparatorTactic::Never,
+        separator_place: context.config.match_pattern_separator_break_point(),
         shape: pat_shape,
         ends_with_newline: false,
         preserve_newline: false,
@@ -1686,12 +1692,20 @@ fn flatten_arm_body<'a>(context: &'a RewriteContext, body: &'a ast::Expr) -> (bo
             if !is_unsafe_block(block) && is_simple_block(block, context.codemap) =>
         {
             if let ast::StmtKind::Expr(ref expr) = block.stmts[0].node {
-                (expr.can_be_overflowed(context, 1), &**expr)
+                (
+                    !context.config.multiline_match_arm_forces_block() &&
+                        expr.can_be_overflowed(context, 1),
+                    &**expr,
+                )
             } else {
                 (false, &*body)
             }
         }
-        _ => (body.can_be_overflowed(context, 1), &*body),
+        _ => (
+            !context.config.multiline_match_arm_forces_block() &&
+                body.can_be_overflowed(context, 1),
+            &*body,
+        ),
     }
 }
 
@@ -1703,9 +1717,9 @@ fn rewrite_match_body(
     has_guard: bool,
     is_last: bool,
 ) -> Option<String> {
-    let (extend, body) = flatten_arm_body(context, &body);
+    let (extend, body) = flatten_arm_body(context, body);
 
-    let comma = arm_comma(&context.config, body, is_last);
+    let comma = arm_comma(context.config, body, is_last);
     let alt_block_sep = String::from("\n") + &shape.indent.block_only().to_string(context.config);
     let alt_block_sep = alt_block_sep.as_str();
     let (is_block, is_empty_block) = if let ast::ExprKind::Block(ref block) = body.node {
@@ -1771,7 +1785,7 @@ fn rewrite_match_body(
     // Let's try and get the arm body on the same line as the condition.
     // 4 = ` => `.len()
     let orig_body_shape = shape
-        .offset_left(extra_offset(&pats_str, shape) + 4)
+        .offset_left(extra_offset(pats_str, shape) + 4)
         .and_then(|shape| shape.sub_width(comma.len()));
     let orig_body = if let Some(body_shape) = orig_body_shape {
         let rewrite = nop_block_collapse(
@@ -1957,7 +1971,7 @@ fn string_requires_rewrite(
     string: &str,
     shape: Shape,
 ) -> bool {
-    if context.codemap.lookup_char_pos(span.lo).col.0 != shape.indent.width() {
+    if context.codemap.lookup_char_pos(span.lo()).col.0 != shape.indent.width() {
         return true;
     }
 
@@ -1966,10 +1980,8 @@ fn string_requires_rewrite(
             if line.len() > shape.width {
                 return true;
             }
-        } else {
-            if line.len() > shape.width + shape.indent.width() {
-                return true;
-            }
+        } else if line.len() > shape.width + shape.indent.width() {
+            return true;
         }
     }
 
@@ -2030,7 +2042,7 @@ pub fn rewrite_call(
     };
     rewrite_call_inner(
         context,
-        &callee,
+        callee,
         &args.iter().map(|x| &**x).collect::<Vec<_>>(),
         span,
         shape,
@@ -2057,7 +2069,7 @@ pub fn rewrite_call_inner<'a, T>(
     } else {
         1
     };
-    let used_width = extra_offset(&callee_str, shape);
+    let used_width = extra_offset(callee_str, shape);
     let one_line_width = shape
         .width
         .checked_sub(used_width + 2 * paren_overhead)
@@ -2071,7 +2083,7 @@ pub fn rewrite_call_inner<'a, T>(
     ).ok_or(Ordering::Greater)?;
 
     let span_lo = context.codemap.span_after(span, "(");
-    let args_span = mk_sp(span_lo, span.hi);
+    let args_span = mk_sp(span_lo, span.hi());
 
     let (extendable, list_str) = rewrite_call_args(
         context,
@@ -2098,7 +2110,7 @@ pub fn rewrite_call_inner<'a, T>(
     }
 
     let args_shape = shape
-        .sub_width(last_line_width(&callee_str))
+        .sub_width(last_line_width(callee_str))
         .ok_or(Ordering::Less)?;
     Ok(format!(
         "{}{}",
@@ -2130,11 +2142,11 @@ fn rewrite_call_args<'a, T>(
         context.codemap,
         args.iter(),
         ")",
-        |item| item.span().lo,
-        |item| item.span().hi,
+        |item| item.span().lo(),
+        |item| item.span().hi(),
         |item| item.rewrite(context, shape),
-        span.lo,
-        span.hi,
+        span.lo(),
+        span.hi(),
         true,
     );
     let mut item_vec: Vec<_> = items.collect();
@@ -2161,6 +2173,7 @@ fn rewrite_call_args<'a, T>(
         } else {
             context.config.trailing_comma()
         },
+        separator_place: SeparatorPlace::Back,
         shape: shape,
         ends_with_newline: context.use_block_indent() && tactic == DefinitiveListTactic::Vertical,
         preserve_newline: false,
@@ -2183,19 +2196,18 @@ fn try_overflow_last_arg<'a, T>(
 where
     T: Rewrite + Spanned + ToExpr + 'a,
 {
-    let overflow_last = can_be_overflowed(&context, args);
+    let overflow_last = can_be_overflowed(context, args);
 
     // Replace the last item with its first line to see if it fits with
     // first arguments.
     let placeholder = if overflow_last {
         let mut context = context.clone();
         if let Some(expr) = args[args.len() - 1].to_expr() {
-            match expr.node {
-                ast::ExprKind::MethodCall(..) => context.force_one_line_chain = true,
-                _ => (),
+            if let ast::ExprKind::MethodCall(..) = expr.node {
+                context.force_one_line_chain = true;
             }
         }
-        last_arg_shape(&context, &item_vec, shape, args_max_width).and_then(|arg_shape| {
+        last_arg_shape(&context, item_vec, shape, args_max_width).and_then(|arg_shape| {
             rewrite_last_arg_with_overflow(&context, args, &mut item_vec[args.len() - 1], arg_shape)
         })
     } else {
@@ -2233,12 +2245,12 @@ fn try_overflow_last_arg<'a, T>(
 
 fn last_arg_shape(
     context: &RewriteContext,
-    items: &Vec<ListItem>,
+    items: &[ListItem],
     shape: Shape,
     args_max_width: usize,
 ) -> Option<Shape> {
     let overhead = items.iter().rev().skip(1).fold(0, |acc, i| {
-        acc + i.item.as_ref().map_or(0, |s| first_line_width(&s))
+        acc + i.item.as_ref().map_or(0, |s| first_line_width(s))
     });
     let max_width = min(args_max_width, shape.width);
     let arg_indent = if context.use_block_indent() {
@@ -2393,7 +2405,7 @@ pub fn wrap_args_with_parens(
         (context.inside_macro && !args_str.contains('\n') &&
             args_str.len() + paren_overhead(context) <= shape.width) || is_extendable
     {
-        if context.config.spaces_within_parens() && args_str.len() > 0 {
+        if context.config.spaces_within_parens() && !args_str.is_empty() {
             format!("( {} )", args_str)
         } else {
             format!("({})", args_str)
@@ -2425,7 +2437,7 @@ fn rewrite_paren(context: &RewriteContext, subexpr: &ast::Expr, shape: Shape) ->
             .and_then(|s| s.sub_width(paren_overhead))
     );
 
-    let paren_wrapper = |s: &str| if context.config.spaces_within_parens() && s.len() > 0 {
+    let paren_wrapper = |s: &str| if context.config.spaces_within_parens() && !s.is_empty() {
         format!("( {} )", s)
     } else {
         format!("({})", s)
@@ -2485,7 +2497,7 @@ fn rewrite_index(
         (_, Some(ref new_index_str)) if !new_index_str.contains('\n') => Some(format!(
             "{}\n{}{}{}{}",
             expr_str,
-            indent.to_string(&context.config),
+            indent.to_string(context.config),
             lbr,
             new_index_str,
             rbr
@@ -2493,7 +2505,7 @@ fn rewrite_index(
         (None, Some(ref new_index_str)) => Some(format!(
             "{}\n{}{}{}{}",
             expr_str,
-            indent.to_string(&context.config),
+            indent.to_string(context.config),
             lbr,
             new_index_str,
             rbr
@@ -2536,7 +2548,7 @@ enum StructLitField<'a> {
         path_shape,
     ));
 
-    if fields.len() == 0 && base.is_none() {
+    if fields.is_empty() && base.is_none() {
         return Some(format!("{} {{}}", path_str));
     }
 
@@ -2552,7 +2564,7 @@ enum StructLitField<'a> {
             fields,
             context,
             shape,
-            mk_sp(body_lo, span.hi),
+            mk_sp(body_lo, span.hi()),
             one_line_width,
         ))
     } else {
@@ -2562,17 +2574,17 @@ enum StructLitField<'a> {
             .chain(base.into_iter().map(StructLitField::Base));
 
         let span_lo = |item: &StructLitField| match *item {
-            StructLitField::Regular(field) => field.span().lo,
+            StructLitField::Regular(field) => field.span().lo(),
             StructLitField::Base(expr) => {
-                let last_field_hi = fields.last().map_or(span.lo, |field| field.span.hi);
-                let snippet = context.snippet(mk_sp(last_field_hi, expr.span.lo));
+                let last_field_hi = fields.last().map_or(span.lo(), |field| field.span.hi());
+                let snippet = context.snippet(mk_sp(last_field_hi, expr.span.lo()));
                 let pos = snippet.find_uncommented("..").unwrap();
                 last_field_hi + BytePos(pos as u32)
             }
         };
         let span_hi = |item: &StructLitField| match *item {
-            StructLitField::Regular(field) => field.span().hi,
-            StructLitField::Base(expr) => expr.span.hi,
+            StructLitField::Regular(field) => field.span().hi(),
+            StructLitField::Base(expr) => expr.span.hi(),
         };
         let rewrite = |item: &StructLitField| match *item {
             StructLitField::Regular(field) => {
@@ -2594,7 +2606,7 @@ enum StructLitField<'a> {
             span_hi,
             rewrite,
             body_lo,
-            span.hi,
+            span.hi(),
             false,
         );
         let item_vec = items.collect::<Vec<_>>();
@@ -2686,7 +2698,7 @@ pub fn rewrite_field(
                         "{}{}:\n{}{}",
                         attrs_str,
                         name,
-                        expr_offset.to_string(&context.config),
+                        expr_offset.to_string(context.config),
                         s
                     )
                 })
@@ -2743,11 +2755,11 @@ fn rewrite_tuple_in_visual_indent_style<'a, T>(
         context.codemap,
         items,
         ")",
-        |item| item.span().lo,
-        |item| item.span().hi,
+        |item| item.span().lo(),
+        |item| item.span().hi(),
         |item| item.rewrite(context, nested_shape),
         list_lo,
-        span.hi - BytePos(1),
+        span.hi() - BytePos(1),
         false,
     );
     let item_vec: Vec<_> = items.collect();
@@ -2761,6 +2773,7 @@ fn rewrite_tuple_in_visual_indent_style<'a, T>(
         tactic: tactic,
         separator: ",",
         trailing_separator: SeparatorTactic::Never,
+        separator_place: SeparatorPlace::Back,
         shape: shape,
         ends_with_newline: false,
         preserve_newline: false,
@@ -2768,7 +2781,7 @@ fn rewrite_tuple_in_visual_indent_style<'a, T>(
     };
     let list_str = try_opt!(write_list(&item_vec, &fmt));
 
-    if context.config.spaces_within_parens() && list_str.len() > 0 {
+    if context.config.spaces_within_parens() && !list_str.is_empty() {
         Some(format!("( {} )", list_str))
     } else {
         Some(format!("({})", list_str))
@@ -2786,7 +2799,7 @@ pub fn rewrite_tuple<'a, T>(
 {
     debug!("rewrite_tuple {:?}", shape);
     if context.use_block_indent() {
-        // We use the same rule as funcation call for rewriting tuple.
+        // We use the same rule as function calls for rewriting tuples.
         let force_trailing_comma = if context.inside_macro {
             span_ends_with_comma(context, span)
         } else {
@@ -2994,3 +3007,20 @@ fn can_be_overflowed(&self, _: &RewriteContext, _: usize) -> bool {
         false
     }
 }
+
+impl<'a> ToExpr for MacroArg {
+    fn to_expr(&self) -> Option<&ast::Expr> {
+        match self {
+            &MacroArg::Expr(ref expr) => Some(expr),
+            _ => None,
+        }
+    }
+
+    fn can_be_overflowed(&self, context: &RewriteContext, len: usize) -> bool {
+        match self {
+            &MacroArg::Expr(ref expr) => can_be_overflowed_expr(context, expr, len),
+            &MacroArg::Ty(ref ty) => can_be_overflowed_type(context, ty, len),
+            &MacroArg::Pat(..) => false,
+        }
+    }
+}