From 2307d08d2f34ef782a1cc7af7bde57d766acd344 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Sat, 23 Jan 2021 00:50:03 -0500 Subject: [PATCH] Use UFCS instead of method calls in `derive(Debug)`. See issue 81211 for discussion. --- .../src/deriving/debug.rs | 40 ++++++++++++------- compiler/rustc_span/src/symbol.rs | 2 + 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/deriving/debug.rs b/compiler/rustc_builtin_macros/src/deriving/debug.rs index 5c21329069b..55ab9d38385 100644 --- a/compiler/rustc_builtin_macros/src/deriving/debug.rs +++ b/compiler/rustc_builtin_macros/src/deriving/debug.rs @@ -8,6 +8,10 @@ use rustc_span::symbol::{sym, Ident}; use rustc_span::{Span, DUMMY_SP}; +fn make_mut_borrow(cx: &mut ExtCtxt<'_>, sp: Span, expr: P) -> P { + cx.expr(sp, ast::ExprKind::AddrOf(ast::BorrowKind::Ref, ast::Mutability::Mut, expr)) +} + pub fn expand_deriving_debug( cx: &mut ExtCtxt<'_>, span: Span, @@ -67,11 +71,12 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_> let fmt = substr.nonself_args[0].clone(); let mut stmts = Vec::with_capacity(fields.len() + 2); + let fn_path_finish; match vdata { ast::VariantData::Tuple(..) | ast::VariantData::Unit(..) => { // tuple struct/"normal" variant - let expr = - cx.expr_method_call(span, fmt, Ident::new(sym::debug_tuple, span), vec![name]); + let fn_path_debug_tuple = cx.std_path(&[sym::fmt, sym::Formatter, sym::debug_tuple]); + let expr = cx.expr_call_global(span, fn_path_debug_tuple, vec![fmt, name]); stmts.push(cx.stmt_let(span, true, builder, expr)); 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); - let expr = cx.expr_method_call( - span, - builder_expr.clone(), - Ident::new(sym::field, span), - vec![field], - ); + let fn_path_field = cx.std_path(&[sym::fmt, sym::DebugTuple, sym::field]); + let builder_recv = make_mut_borrow(cx, span, builder_expr.clone()); + let expr = cx.expr_call_global(span, fn_path_field, vec![builder_recv, field]); // Use `let _ = expr;` to avoid triggering the // unused_results lint. stmts.push(stmt_let_underscore(cx, span, expr)); } + + fn_path_finish = cx.std_path(&[sym::fmt, sym::DebugTuple, sym::finish]); } ast::VariantData::Struct(..) => { // normal struct/struct variant - let expr = - cx.expr_method_call(span, fmt, Ident::new(sym::debug_struct, span), vec![name]); + let fn_path_debug_struct = + 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)); 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 + 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); - let expr = cx.expr_method_call( + let builder_recv = make_mut_borrow(cx, span, builder_expr.clone()); + let expr = cx.expr_call_global( span, - builder_expr.clone(), - Ident::new(sym::field, span), - vec![name, field], + fn_path_field, + vec![builder_recv, name, field], ); 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)); let block = cx.block(span, stmts); diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index f2f975c0cf9..bc094c12934 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -133,6 +133,8 @@ Copy, Count, Debug, + DebugStruct, + DebugTuple, Decodable, Decoder, Default,