@@ -8,6 +8,10 @@ use rustc_expand::base::{Annotatable, ExtCtxt};
8
8
use rustc_span:: symbol:: { sym, Ident } ;
9
9
use rustc_span:: { Span , DUMMY_SP } ;
10
10
11
+ fn make_mut_borrow ( cx : & mut ExtCtxt < ' _ > , sp : Span , expr : P < Expr > ) -> P < Expr > {
12
+ cx. expr ( sp, ast:: ExprKind :: AddrOf ( ast:: BorrowKind :: Ref , ast:: Mutability :: Mut , expr) )
13
+ }
14
+
11
15
pub fn expand_deriving_debug (
12
16
cx : & mut ExtCtxt < ' _ > ,
13
17
span : Span ,
@@ -67,34 +71,34 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
67
71
let fmt = substr. nonself_args [ 0 ] . clone ( ) ;
68
72
69
73
let mut stmts = Vec :: with_capacity ( fields. len ( ) + 2 ) ;
74
+ let fn_path_finish;
70
75
match vdata {
71
76
ast:: VariantData :: Tuple ( ..) | ast:: VariantData :: Unit ( ..) => {
72
77
// tuple struct/"normal" variant
73
- let expr =
74
- cx. expr_method_call ( span, fmt , Ident :: new ( sym :: debug_tuple , span ) , vec ! [ name] ) ;
78
+ let fn_path_debug_tuple = cx . std_path ( & [ sym :: fmt , sym :: Formatter , sym :: debug_tuple ] ) ;
79
+ let expr = cx. expr_call_global ( span, fn_path_debug_tuple , vec ! [ fmt , name] ) ;
75
80
stmts. push ( cx. stmt_let ( span, true , builder, expr) ) ;
76
81
77
82
for field in fields {
78
83
// Use double indirection to make sure this works for unsized types
79
84
let field = cx. expr_addr_of ( field. span , field. self_ . clone ( ) ) ;
80
85
let field = cx. expr_addr_of ( field. span , field) ;
81
86
82
- let expr = cx. expr_method_call (
83
- span,
84
- builder_expr. clone ( ) ,
85
- Ident :: new ( sym:: field, span) ,
86
- vec ! [ field] ,
87
- ) ;
87
+ let fn_path_field = cx. std_path ( & [ sym:: fmt, sym:: DebugTuple , sym:: field] ) ;
88
+ let builder_recv = make_mut_borrow ( cx, span, builder_expr. clone ( ) ) ;
89
+ let expr = cx. expr_call_global ( span, fn_path_field, vec ! [ builder_recv, field] ) ;
88
90
89
91
// Use `let _ = expr;` to avoid triggering the
90
92
// unused_results lint.
91
93
stmts. push ( stmt_let_underscore ( cx, span, expr) ) ;
92
94
}
95
+
96
+ fn_path_finish = cx. std_path ( & [ sym:: fmt, sym:: DebugTuple , sym:: finish] ) ;
93
97
}
94
98
ast:: VariantData :: Struct ( ..) => {
95
99
// normal struct/struct variant
96
- let expr =
97
- cx. expr_method_call ( span, fmt , Ident :: new ( sym :: debug_struct , span ) , vec ! [ name] ) ;
100
+ let fn_path_debug_struct = cx . std_path ( & [ sym :: fmt , sym :: Formatter , sym :: debug_struct ] ) ;
101
+ let expr = cx. expr_call_global ( span, fn_path_debug_struct , vec ! [ fmt , name] ) ;
98
102
stmts. push ( cx. stmt_let ( DUMMY_SP , true , builder, expr) ) ;
99
103
100
104
for field in fields {
@@ -104,20 +108,20 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
104
108
) ;
105
109
106
110
// Use double indirection to make sure this works for unsized types
111
+ let fn_path_field = cx. std_path ( & [ sym:: fmt, sym:: DebugStruct , sym:: field] ) ;
107
112
let field = cx. expr_addr_of ( field. span , field. self_ . clone ( ) ) ;
108
113
let field = cx. expr_addr_of ( field. span , field) ;
109
- let expr = cx. expr_method_call (
110
- span,
111
- builder_expr. clone ( ) ,
112
- Ident :: new ( sym:: field, span) ,
113
- vec ! [ name, field] ,
114
- ) ;
114
+ let builder_recv = make_mut_borrow ( cx, span, builder_expr. clone ( ) ) ;
115
+ let expr =
116
+ cx. expr_call_global ( span, fn_path_field, vec ! [ builder_recv, name, field] ) ;
115
117
stmts. push ( stmt_let_underscore ( cx, span, expr) ) ;
116
118
}
119
+ fn_path_finish = cx. std_path ( & [ sym:: fmt, sym:: DebugStruct , sym:: finish] ) ;
117
120
}
118
121
}
119
122
120
- let expr = cx. expr_method_call ( span, builder_expr, Ident :: new ( sym:: finish, span) , vec ! [ ] ) ;
123
+ let builder_recv = make_mut_borrow ( cx, span, builder_expr) ;
124
+ let expr = cx. expr_call_global ( span, fn_path_finish, vec ! [ builder_recv] ) ;
121
125
122
126
stmts. push ( cx. stmt_expr ( expr) ) ;
123
127
let block = cx. block ( span, stmts) ;
0 commit comments