Skip to content

Commit 9545094

Browse files
committed
Auto merge of rust-lang#107599 - clubby789:debug-less-ref, r=nnethercote
Don't generate unecessary `&&self.field` in deriving Debug Since unsized fields may only be the last one in a struct, we only need to generate a double reference (`&&self.field`) for the final one. cc `@nnethercote`
2 parents a94b9fd + d8651aa commit 9545094

File tree

2 files changed

+27
-12
lines changed

2 files changed

+27
-12
lines changed

compiler/rustc_builtin_macros/src/deriving/debug.rs

+20-5
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,21 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
7676
// The number of fields that can be handled without an array.
7777
const CUTOFF: usize = 5;
7878

79+
fn expr_for_field(
80+
cx: &ExtCtxt<'_>,
81+
field: &FieldInfo,
82+
index: usize,
83+
len: usize,
84+
) -> ast::ptr::P<ast::Expr> {
85+
if index < len - 1 {
86+
field.self_expr.clone()
87+
} else {
88+
// Unsized types need an extra indirection, but only the last field
89+
// may be unsized.
90+
cx.expr_addr_of(field.span, field.self_expr.clone())
91+
}
92+
}
93+
7994
if fields.is_empty() {
8095
// Special case for no fields.
8196
let fn_path_write_str = cx.std_path(&[sym::fmt, sym::Formatter, sym::write_str]);
@@ -98,8 +113,8 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
98113
let name = cx.expr_str(field.span, field.name.unwrap().name);
99114
args.push(name);
100115
}
101-
// Use an extra indirection to make sure this works for unsized types.
102-
let field = cx.expr_addr_of(field.span, field.self_expr.clone());
116+
117+
let field = expr_for_field(cx, field, i, fields.len());
103118
args.push(field);
104119
}
105120
let expr = cx.expr_call_global(span, fn_path_debug, args);
@@ -109,13 +124,13 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
109124
let mut name_exprs = Vec::with_capacity(fields.len());
110125
let mut value_exprs = Vec::with_capacity(fields.len());
111126

112-
for field in fields {
127+
for i in 0..fields.len() {
128+
let field = &fields[i];
113129
if is_struct {
114130
name_exprs.push(cx.expr_str(field.span, field.name.unwrap().name));
115131
}
116132

117-
// Use an extra indirection to make sure this works for unsized types.
118-
let field = cx.expr_addr_of(field.span, field.self_expr.clone());
133+
let field = expr_for_field(cx, field, i, fields.len());
119134
value_exprs.push(field);
120135
}
121136

tests/ui/deriving/deriving-all-codegen.stdout

+7-7
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ impl ::core::marker::Copy for Point { }
9898
impl ::core::fmt::Debug for Point {
9999
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
100100
::core::fmt::Formatter::debug_struct_field2_finish(f, "Point", "x",
101-
&&self.x, "y", &&self.y)
101+
&self.x, "y", &&self.y)
102102
}
103103
}
104104
#[automatically_derived]
@@ -183,7 +183,7 @@ impl ::core::marker::Copy for PackedPoint { }
183183
impl ::core::fmt::Debug for PackedPoint {
184184
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
185185
::core::fmt::Formatter::debug_struct_field2_finish(f, "PackedPoint",
186-
"x", &&{ self.x }, "y", &&{ self.y })
186+
"x", &{ self.x }, "y", &&{ self.y })
187187
}
188188
}
189189
#[automatically_derived]
@@ -277,8 +277,8 @@ impl ::core::fmt::Debug for Big {
277277
let names: &'static _ =
278278
&["b1", "b2", "b3", "b4", "b5", "b6", "b7", "b8"];
279279
let values: &[&dyn ::core::fmt::Debug] =
280-
&[&&self.b1, &&self.b2, &&self.b3, &&self.b4, &&self.b5,
281-
&&self.b6, &&self.b7, &&self.b8];
280+
&[&self.b1, &self.b2, &self.b3, &self.b4, &self.b5, &self.b6,
281+
&self.b7, &&self.b8];
282282
::core::fmt::Formatter::debug_struct_fields_finish(f, "Big", names,
283283
values)
284284
}
@@ -565,7 +565,7 @@ impl<T: ::core::fmt::Debug + Trait, U: ::core::fmt::Debug> ::core::fmt::Debug
565565
for Generic<T, U> where T::A: ::core::fmt::Debug {
566566
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
567567
::core::fmt::Formatter::debug_struct_field3_finish(f, "Generic", "t",
568-
&&self.t, "ta", &&self.ta, "u", &&self.u)
568+
&self.t, "ta", &self.ta, "u", &&self.u)
569569
}
570570
}
571571
#[automatically_derived]
@@ -682,7 +682,7 @@ impl<T: ::core::fmt::Debug + ::core::marker::Copy + Trait,
682682
{
683683
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
684684
::core::fmt::Formatter::debug_tuple_field3_finish(f, "PackedGeneric",
685-
&&{ self.0 }, &&{ self.1 }, &&{ self.2 })
685+
&{ self.0 }, &{ self.1 }, &&{ self.2 })
686686
}
687687
}
688688
#[automatically_derived]
@@ -1084,7 +1084,7 @@ impl ::core::fmt::Debug for Mixed {
10841084
&__self_0),
10851085
Mixed::S { d1: __self_0, d2: __self_1 } =>
10861086
::core::fmt::Formatter::debug_struct_field2_finish(f, "S",
1087-
"d1", &__self_0, "d2", &__self_1),
1087+
"d1", __self_0, "d2", &__self_1),
10881088
}
10891089
}
10901090
}

0 commit comments

Comments
 (0)