Skip to content

Commit

Permalink
Don't chain method calls in #[derive(Debug)]
Browse files Browse the repository at this point in the history
  • Loading branch information
sfackler committed Nov 4, 2015
1 parent c340ea1 commit d0bc6a1
Show file tree
Hide file tree
Showing 2 changed files with 536 additions and 24 deletions.
59 changes: 35 additions & 24 deletions src/libsyntax/ext/deriving/debug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -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)
}
Loading

0 comments on commit d0bc6a1

Please sign in to comment.