summary refs log tree commit diff
path: root/src/libsyntax/ext
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-11-05 18:15:26 +0000
committerbors <bors@rust-lang.org>2015-11-05 18:15:26 +0000
commit3a0409d29129d7128a55c93239d81a00d121a200 (patch)
tree8020bf424488b8cb6eccc29d0f5e17c8ad0efba2 /src/libsyntax/ext
parent74185aff27a2cfed37ea553242f6e7248c820a8c (diff)
parentd0bc6a1f49f2802d603acf086ed54d976a79d703 (diff)
downloadrust-3a0409d29129d7128a55c93239d81a00d121a200.tar.gz
rust-3a0409d29129d7128a55c93239d81a00d121a200.zip
Auto merge of #29565 - sfackler:issue-29540, r=huonw
Closes #29540

r? @huonw
Diffstat (limited to 'src/libsyntax/ext')
-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)
 }