about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorSteven Fackler <sfackler@gmail.com>2015-11-03 22:48:28 -0800
committerSteven Fackler <sfackler@gmail.com>2015-11-03 22:48:28 -0800
commitd0bc6a1f49f2802d603acf086ed54d976a79d703 (patch)
tree6edb11e6b0f76ff0aa5412a8788de5873bc46913 /src/libsyntax
parentc340ea1de5dba6d0184103b9d67e290e3ea02981 (diff)
downloadrust-d0bc6a1f49f2802d603acf086ed54d976a79d703.tar.gz
rust-d0bc6a1f49f2802d603acf086ed54d976a79d703.zip
Don't chain method calls in #[derive(Debug)]
Closes #29540
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ext/deriving/debug.rs59
1 files changed, 35 insertions, 24 deletions
diff --git a/src/libsyntax/ext/deriving/debug.rs b/src/libsyntax/ext/deriving/debug.rs
index 537375f7084..8a180e6c093 100644
--- a/src/libsyntax/ext/deriving/debug.rs
+++ b/src/libsyntax/ext/deriving/debug.rs
@@ -72,34 +72,40 @@ fn show_substructure(cx: &mut ExtCtxt, span: Span,
     let span = Span { expn_id: cx.backtrace(), .. span };
     let name = cx.expr_lit(span, ast::Lit_::LitStr(ident.name.as_str(),
                                                    ast::StrStyle::CookedStr));
-    let mut expr = substr.nonself_args[0].clone();
+    let builder = token::str_to_ident("builder");
+    let builder_expr = cx.expr_ident(span, builder.clone());
 
-    match *substr.fields {
-        Struct(ref fields) | EnumMatching(_, _, ref fields) => {
+    let fmt = substr.nonself_args[0].clone();
 
+    let stmts = match *substr.fields {
+        Struct(ref fields) | EnumMatching(_, _, ref fields) => {
+            let mut stmts = vec![];
             if fields.is_empty() || fields[0].name.is_none() {
                 // tuple struct/"normal" variant
-                expr = cx.expr_method_call(span,
-                                           expr,
-                                           token::str_to_ident("debug_tuple"),
-                                           vec![name]);
+                let expr = cx.expr_method_call(span,
+                                               fmt,
+                                               token::str_to_ident("debug_tuple"),
+                                               vec![name]);
+                stmts.push(cx.stmt_let(span, true, builder, expr));
 
                 for field in fields {
                     // Use double indirection to make sure this works for unsized types
                     let field = cx.expr_addr_of(field.span, field.self_.clone());
                     let field = cx.expr_addr_of(field.span, field);
 
-                    expr = cx.expr_method_call(span,
-                                               expr,
-                                               token::str_to_ident("field"),
-                                               vec![field]);
+                    let expr = cx.expr_method_call(span,
+                                                   builder_expr.clone(),
+                                                   token::str_to_ident("field"),
+                                                   vec![field]);
+                    stmts.push(cx.stmt_expr(expr));
                 }
             } else {
                 // normal struct/struct variant
-                expr = cx.expr_method_call(span,
-                                           expr,
-                                           token::str_to_ident("debug_struct"),
-                                           vec![name]);
+                let expr = cx.expr_method_call(span,
+                                               fmt,
+                                               token::str_to_ident("debug_struct"),
+                                               vec![name]);
+                stmts.push(cx.stmt_let(span, true, builder, expr));
 
                 for field in fields {
                     let name = cx.expr_lit(field.span, ast::Lit_::LitStr(
@@ -109,18 +115,23 @@ fn show_substructure(cx: &mut ExtCtxt, span: Span,
                     // Use double indirection to make sure this works for unsized types
                     let field = cx.expr_addr_of(field.span, field.self_.clone());
                     let field = cx.expr_addr_of(field.span, field);
-                    expr = cx.expr_method_call(span,
-                                               expr,
-                                               token::str_to_ident("field"),
-                                               vec![name, field]);
+                    let expr = cx.expr_method_call(span,
+                                                   builder_expr.clone(),
+                                                   token::str_to_ident("field"),
+                                                   vec![name, field]);
+                    stmts.push(cx.stmt_expr(expr));
                 }
             }
+            stmts
         }
         _ => unreachable!()
-    }
+    };
+
+    let expr = cx.expr_method_call(span,
+                                   builder_expr,
+                                   token::str_to_ident("finish"),
+                                   vec![]);
 
-    cx.expr_method_call(span,
-                        expr,
-                        token::str_to_ident("finish"),
-                        vec![])
+    let block = cx.block(span, stmts, Some(expr));
+    cx.expr_block(block)
 }