Use UFCS instead of method calls in `derive(Debug)`. See issue 81211 for discussion.

This commit is contained in:
Felix S. Klock II 2021-01-23 00:50:03 -05:00
parent 02b85d7220
commit 2307d08d2f
2 changed files with 27 additions and 15 deletions

View File

@ -8,6 +8,10 @@ use rustc_expand::base::{Annotatable, ExtCtxt};
use rustc_span::symbol::{sym, Ident}; use rustc_span::symbol::{sym, Ident};
use rustc_span::{Span, DUMMY_SP}; use rustc_span::{Span, DUMMY_SP};
fn make_mut_borrow(cx: &mut ExtCtxt<'_>, sp: Span, expr: P<Expr>) -> P<Expr> {
cx.expr(sp, ast::ExprKind::AddrOf(ast::BorrowKind::Ref, ast::Mutability::Mut, expr))
}
pub fn expand_deriving_debug( pub fn expand_deriving_debug(
cx: &mut ExtCtxt<'_>, cx: &mut ExtCtxt<'_>,
span: Span, span: Span,
@ -67,11 +71,12 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
let fmt = substr.nonself_args[0].clone(); let fmt = substr.nonself_args[0].clone();
let mut stmts = Vec::with_capacity(fields.len() + 2); let mut stmts = Vec::with_capacity(fields.len() + 2);
let fn_path_finish;
match vdata { match vdata {
ast::VariantData::Tuple(..) | ast::VariantData::Unit(..) => { ast::VariantData::Tuple(..) | ast::VariantData::Unit(..) => {
// tuple struct/"normal" variant // tuple struct/"normal" variant
let expr = let fn_path_debug_tuple = cx.std_path(&[sym::fmt, sym::Formatter, sym::debug_tuple]);
cx.expr_method_call(span, fmt, Ident::new(sym::debug_tuple, span), vec![name]); let expr = cx.expr_call_global(span, fn_path_debug_tuple, vec![fmt, name]);
stmts.push(cx.stmt_let(span, true, builder, expr)); stmts.push(cx.stmt_let(span, true, builder, expr));
for field in fields { for field in fields {
@ -79,22 +84,24 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
let field = cx.expr_addr_of(field.span, field.self_.clone()); let field = cx.expr_addr_of(field.span, field.self_.clone());
let field = cx.expr_addr_of(field.span, field); let field = cx.expr_addr_of(field.span, field);
let expr = cx.expr_method_call( let fn_path_field = cx.std_path(&[sym::fmt, sym::DebugTuple, sym::field]);
span, let builder_recv = make_mut_borrow(cx, span, builder_expr.clone());
builder_expr.clone(), let expr = cx.expr_call_global(span, fn_path_field, vec![builder_recv, field]);
Ident::new(sym::field, span),
vec![field],
);
// Use `let _ = expr;` to avoid triggering the // Use `let _ = expr;` to avoid triggering the
// unused_results lint. // unused_results lint.
stmts.push(stmt_let_underscore(cx, span, expr)); stmts.push(stmt_let_underscore(cx, span, expr));
} }
fn_path_finish = cx.std_path(&[sym::fmt, sym::DebugTuple, sym::finish]);
} }
ast::VariantData::Struct(..) => { ast::VariantData::Struct(..) => {
// normal struct/struct variant // normal struct/struct variant
let expr = let fn_path_debug_struct =
cx.expr_method_call(span, fmt, Ident::new(sym::debug_struct, span), vec![name]); cx.std_path(&[sym::fmt, sym::Formatter, sym::debug_struct]);
let expr = cx.expr_call_global(
span, fn_path_debug_struct, vec![fmt, name]
);
stmts.push(cx.stmt_let(DUMMY_SP, true, builder, expr)); stmts.push(cx.stmt_let(DUMMY_SP, true, builder, expr));
for field in fields { for field in fields {
@ -104,20 +111,23 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
); );
// Use double indirection to make sure this works for unsized types // Use double indirection to make sure this works for unsized types
let fn_path_field = cx.std_path(&[sym::fmt, sym::DebugStruct, sym::field]);
let field = cx.expr_addr_of(field.span, field.self_.clone()); let field = cx.expr_addr_of(field.span, field.self_.clone());
let field = cx.expr_addr_of(field.span, field); let field = cx.expr_addr_of(field.span, field);
let expr = cx.expr_method_call( let builder_recv = make_mut_borrow(cx, span, builder_expr.clone());
let expr = cx.expr_call_global(
span, span,
builder_expr.clone(), fn_path_field,
Ident::new(sym::field, span), vec![builder_recv, name, field],
vec![name, field],
); );
stmts.push(stmt_let_underscore(cx, span, expr)); stmts.push(stmt_let_underscore(cx, span, expr));
} }
fn_path_finish = cx.std_path(&[sym::fmt, sym::DebugStruct, sym::finish]);
} }
} }
let expr = cx.expr_method_call(span, builder_expr, Ident::new(sym::finish, span), vec![]); let builder_recv = make_mut_borrow(cx, span, builder_expr);
let expr = cx.expr_call_global(span, fn_path_finish, vec![builder_recv]);
stmts.push(cx.stmt_expr(expr)); stmts.push(cx.stmt_expr(expr));
let block = cx.block(span, stmts); let block = cx.block(span, stmts);

View File

@ -133,6 +133,8 @@ symbols! {
Copy, Copy,
Count, Count,
Debug, Debug,
DebugStruct,
DebugTuple,
Decodable, Decodable,
Decoder, Decoder,
Default, Default,