diff options
| author | Steven Fackler <sfackler@gmail.com> | 2015-11-03 22:48:28 -0800 |
|---|---|---|
| committer | Steven Fackler <sfackler@gmail.com> | 2015-11-03 22:48:28 -0800 |
| commit | d0bc6a1f49f2802d603acf086ed54d976a79d703 (patch) | |
| tree | 6edb11e6b0f76ff0aa5412a8788de5873bc46913 /src/libsyntax | |
| parent | c340ea1de5dba6d0184103b9d67e290e3ea02981 (diff) | |
| download | rust-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.rs | 59 |
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) } |
