Auto merge of #29565 - sfackler:issue-29540, r=huonw

Closes #29540

r? @huonw
This commit is contained in:
bors
2015-11-05 18:15:26 +00:00
2 changed files with 536 additions and 24 deletions

View File

@@ -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 {
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!()
}
};
cx.expr_method_call(span,
expr,
token::str_to_ident("finish"),
vec![])
let expr = cx.expr_method_call(span,
builder_expr,
token::str_to_ident("finish"),
vec![]);
let block = cx.block(span, stmts, Some(expr));
cx.expr_block(block)
}