Use UFCS instead of method calls in derive(Debug)
. See issue 81211 for discussion.
This commit is contained in:
parent
02b85d7220
commit
2307d08d2f
2 changed files with 27 additions and 15 deletions
|
@ -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);
|
||||||
|
|
|
@ -133,6 +133,8 @@ symbols! {
|
||||||
Copy,
|
Copy,
|
||||||
Count,
|
Count,
|
||||||
Debug,
|
Debug,
|
||||||
|
DebugStruct,
|
||||||
|
DebugTuple,
|
||||||
Decodable,
|
Decodable,
|
||||||
Decoder,
|
Decoder,
|
||||||
Default,
|
Default,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue