Skip to content

Commit 186f7ae

Browse files
committed
Auto merge of #81294 - pnkfelix:issue-81211-use-ufcs-in-derive-debug, r=oli-obk
Use ufcs in derive(Debug) Cc #81211. (Arguably this *is* the fix for it.)
2 parents 6ad11e2 + 1783c47 commit 186f7ae

File tree

6 files changed

+315
-43
lines changed

6 files changed

+315
-43
lines changed

compiler/rustc_builtin_macros/src/deriving/debug.rs

+21-17
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ use rustc_expand::base::{Annotatable, ExtCtxt};
88
use rustc_span::symbol::{sym, Ident};
99
use rustc_span::{Span, DUMMY_SP};
1010

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+
1115
pub fn expand_deriving_debug(
1216
cx: &mut ExtCtxt<'_>,
1317
span: Span,
@@ -67,34 +71,34 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
6771
let fmt = substr.nonself_args[0].clone();
6872

6973
let mut stmts = Vec::with_capacity(fields.len() + 2);
74+
let fn_path_finish;
7075
match vdata {
7176
ast::VariantData::Tuple(..) | ast::VariantData::Unit(..) => {
7277
// 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]);
7580
stmts.push(cx.stmt_let(span, true, builder, expr));
7681

7782
for field in fields {
7883
// Use double indirection to make sure this works for unsized types
7984
let field = cx.expr_addr_of(field.span, field.self_.clone());
8085
let field = cx.expr_addr_of(field.span, field);
8186

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]);
8890

8991
// Use `let _ = expr;` to avoid triggering the
9092
// unused_results lint.
9193
stmts.push(stmt_let_underscore(cx, span, expr));
9294
}
95+
96+
fn_path_finish = cx.std_path(&[sym::fmt, sym::DebugTuple, sym::finish]);
9397
}
9498
ast::VariantData::Struct(..) => {
9599
// 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]);
98102
stmts.push(cx.stmt_let(DUMMY_SP, true, builder, expr));
99103

100104
for field in fields {
@@ -104,20 +108,20 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
104108
);
105109

106110
// 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]);
107112
let field = cx.expr_addr_of(field.span, field.self_.clone());
108113
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]);
115117
stmts.push(stmt_let_underscore(cx, span, expr));
116118
}
119+
fn_path_finish = cx.std_path(&[sym::fmt, sym::DebugStruct, sym::finish]);
117120
}
118121
}
119122

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]);
121125

122126
stmts.push(cx.stmt_expr(expr));
123127
let block = cx.block(span, stmts);

compiler/rustc_span/src/symbol.rs

+2
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,8 @@ symbols! {
133133
Copy,
134134
Count,
135135
Debug,
136+
DebugStruct,
137+
DebugTuple,
136138
Decodable,
137139
Decoder,
138140
Default,

src/test/run-make-fulldeps/coverage-spanview/expected_mir_dump.partial_eq/partial_eq.{impl#7}-fmt.-------.InstrumentCoverage.0.html

+30-26
Original file line numberDiff line numberDiff line change
@@ -78,32 +78,36 @@
7878
4:17-4:22: @0[13]: _8 = &amp;(*_9)
7979
4:17-4:22: @0.Call: _6 = Formatter::debug_struct(move _7, move _8) -&gt; [return: bb1, unwind: bb6]
8080
4:17-4:22: @1[2]: FakeRead(ForLet, _6)
81-
4:17-4:22: @1[6]: _11 = &amp;mut _6
82-
4:17-4:22: @1[9]: _13 = const &quot;major&quot;
83-
4:17-4:22: @1[10]: _12 = &amp;(*_13)
84-
4:17-4:22: @1[15]: _17 = &amp;(*_3)
85-
4:17-4:22: @1[16]: _16 = &amp;_17
86-
4:17-4:22: @1[17]: _15 = &amp;(*_16)
87-
4:17-4:22: @1[18]: _14 = move _15 as &amp;dyn std::fmt::Debug (Pointer(Unsize))
88-
4:17-4:22: @1.Call: _10 = DebugStruct::field(move _11, move _12, move _14) -&gt; [return: bb2, unwind: bb6]
89-
4:17-4:22: @2[9]: _19 = &amp;mut _6
90-
4:17-4:22: @2[12]: _21 = const &quot;minor&quot;
91-
4:17-4:22: @2[13]: _20 = &amp;(*_21)
92-
4:17-4:22: @2[18]: _25 = &amp;(*_4)
93-
4:17-4:22: @2[19]: _24 = &amp;_25
94-
4:17-4:22: @2[20]: _23 = &amp;(*_24)
95-
4:17-4:22: @2[21]: _22 = move _23 as &amp;dyn std::fmt::Debug (Pointer(Unsize))
96-
4:17-4:22: @2.Call: _18 = DebugStruct::field(move _19, move _20, move _22) -&gt; [return: bb3, unwind: bb6]
97-
4:17-4:22: @3[9]: _27 = &amp;mut _6
98-
4:17-4:22: @3[12]: _29 = const &quot;patch&quot;
99-
4:17-4:22: @3[13]: _28 = &amp;(*_29)
100-
4:17-4:22: @3[18]: _33 = &amp;(*_5)
101-
4:17-4:22: @3[19]: _32 = &amp;_33
102-
4:17-4:22: @3[20]: _31 = &amp;(*_32)
103-
4:17-4:22: @3[21]: _30 = move _31 as &amp;dyn std::fmt::Debug (Pointer(Unsize))
104-
4:17-4:22: @3.Call: _26 = DebugStruct::field(move _27, move _28, move _30) -&gt; [return: bb4, unwind: bb6]
105-
4:17-4:22: @4[8]: _34 = &amp;mut _6
106-
4:17-4:22: @4.Call: _0 = DebugStruct::finish(move _34) -&gt; [return: bb5, unwind: bb6]
81+
4:17-4:22: @1[7]: _12 = &amp;mut _6
82+
4:17-4:22: @1[8]: _11 = &amp;mut (*_12)
83+
4:17-4:22: @1[11]: _14 = const &quot;major&quot;
84+
4:17-4:22: @1[12]: _13 = &amp;(*_14)
85+
4:17-4:22: @1[17]: _18 = &amp;(*_3)
86+
4:17-4:22: @1[18]: _17 = &amp;_18
87+
4:17-4:22: @1[19]: _16 = &amp;(*_17)
88+
4:17-4:22: @1[20]: _15 = move _16 as &amp;dyn std::fmt::Debug (Pointer(Unsize))
89+
4:17-4:22: @1.Call: _10 = DebugStruct::field(move _11, move _13, move _15) -&gt; [return: bb2, unwind: bb6]
90+
4:17-4:22: @2[11]: _21 = &amp;mut _6
91+
4:17-4:22: @2[12]: _20 = &amp;mut (*_21)
92+
4:17-4:22: @2[15]: _23 = const &quot;minor&quot;
93+
4:17-4:22: @2[16]: _22 = &amp;(*_23)
94+
4:17-4:22: @2[21]: _27 = &amp;(*_4)
95+
4:17-4:22: @2[22]: _26 = &amp;_27
96+
4:17-4:22: @2[23]: _25 = &amp;(*_26)
97+
4:17-4:22: @2[24]: _24 = move _25 as &amp;dyn std::fmt::Debug (Pointer(Unsize))
98+
4:17-4:22: @2.Call: _19 = DebugStruct::field(move _20, move _22, move _24) -&gt; [return: bb3, unwind: bb6]
99+
4:17-4:22: @3[11]: _30 = &amp;mut _6
100+
4:17-4:22: @3[12]: _29 = &amp;mut (*_30)
101+
4:17-4:22: @3[15]: _32 = const &quot;patch&quot;
102+
4:17-4:22: @3[16]: _31 = &amp;(*_32)
103+
4:17-4:22: @3[21]: _36 = &amp;(*_5)
104+
4:17-4:22: @3[22]: _35 = &amp;_36
105+
4:17-4:22: @3[23]: _34 = &amp;(*_35)
106+
4:17-4:22: @3[24]: _33 = move _34 as &amp;dyn std::fmt::Debug (Pointer(Unsize))
107+
4:17-4:22: @3.Call: _28 = DebugStruct::field(move _29, move _31, move _33) -&gt; [return: bb4, unwind: bb6]
108+
4:17-4:22: @4[10]: _38 = &amp;mut _6
109+
4:17-4:22: @4[11]: _37 = &amp;mut (*_38)
110+
4:17-4:22: @4.Call: _0 = DebugStruct::finish(move _37) -&gt; [return: bb5, unwind: bb6]
107111
4:22-4:22: @5.Return: return"><span class="annotation">@0,1,2,3,4,5⦊</span>Debug<span class="annotation">⦉@0,1,2,3,4,5</span></span></span></span></div>
108112
</body>
109113
</html>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// run-pass
2+
#![allow(warnings)]
3+
4+
#[derive(Debug)]
5+
pub struct Bar { pub t: () }
6+
7+
impl<T> Access for T {}
8+
pub trait Access {
9+
fn field(&self, _: impl Sized, _: impl Sized) {
10+
panic!("got into Access::field");
11+
}
12+
13+
fn finish(&self) -> Result<(), std::fmt::Error> {
14+
panic!("got into Access::finish");
15+
}
16+
17+
fn debug_struct(&self, _: impl Sized, _: impl Sized) {
18+
panic!("got into Access::debug_struct");
19+
}
20+
}
21+
22+
impl<T> MutAccess for T {}
23+
pub trait MutAccess {
24+
fn field(&mut self, _: impl Sized, _: impl Sized) {
25+
panic!("got into MutAccess::field");
26+
}
27+
28+
fn finish(&mut self) -> Result<(), std::fmt::Error> {
29+
panic!("got into MutAccess::finish");
30+
}
31+
32+
fn debug_struct(&mut self, _: impl Sized, _: impl Sized) {
33+
panic!("got into MutAccess::debug_struct");
34+
}
35+
}
36+
37+
fn main() {
38+
let bar = Bar { t: () };
39+
assert_eq!("Bar { t: () }", format!("{:?}", bar));
40+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// run-pass
2+
#![allow(warnings)]
3+
4+
#[derive(Debug)]
5+
pub struct Foo<T>(pub T);
6+
7+
use std::fmt;
8+
9+
impl<T> Field for T {}
10+
impl<T> Finish for T {}
11+
impl Dt for &mut fmt::Formatter<'_> {}
12+
13+
pub trait Field {
14+
fn field(&self, _: impl Sized) {
15+
panic!("got into field");
16+
}
17+
}
18+
pub trait Finish {
19+
fn finish(&self) -> Result<(), std::fmt::Error> {
20+
panic!("got into finish");
21+
}
22+
}
23+
pub trait Dt {
24+
fn debug_tuple(&self, _: &str) {
25+
panic!("got into debug_tuple");
26+
}
27+
}
28+
29+
fn main() {
30+
let foo = Foo(());
31+
assert_eq!("Foo(())", format!("{:?}", foo));
32+
}

0 commit comments

Comments
 (0)