diff --git a/compiler/rustc_builtin_macros/src/deriving/debug.rs b/compiler/rustc_builtin_macros/src/deriving/debug.rs index 897048f6421..74e2597830e 100644 --- a/compiler/rustc_builtin_macros/src/deriving/debug.rs +++ b/compiler/rustc_builtin_macros/src/deriving/debug.rs @@ -76,6 +76,21 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_> // The number of fields that can be handled without an array. const CUTOFF: usize = 5; + fn expr_for_field( + cx: &ExtCtxt<'_>, + field: &FieldInfo, + index: usize, + len: usize, + ) -> ast::ptr::P { + if index < len - 1 { + field.self_expr.clone() + } else { + // Unsized types need an extra indirection, but only the last field + // may be unsized. + cx.expr_addr_of(field.span, field.self_expr.clone()) + } + } + if fields.is_empty() { // Special case for no fields. 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<'_> let name = cx.expr_str(field.span, field.name.unwrap().name); args.push(name); } - // Use an extra indirection to make sure this works for unsized types. - let field = cx.expr_addr_of(field.span, field.self_expr.clone()); + + let field = expr_for_field(cx, field, i, fields.len()); args.push(field); } 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<'_> let mut name_exprs = Vec::with_capacity(fields.len()); let mut value_exprs = Vec::with_capacity(fields.len()); - for field in fields { + for i in 0..fields.len() { + let field = &fields[i]; if is_struct { name_exprs.push(cx.expr_str(field.span, field.name.unwrap().name)); } - // Use an extra indirection to make sure this works for unsized types. - let field = cx.expr_addr_of(field.span, field.self_expr.clone()); + let field = expr_for_field(cx, field, i, fields.len()); value_exprs.push(field); } diff --git a/tests/ui/deriving/deriving-all-codegen.stdout b/tests/ui/deriving/deriving-all-codegen.stdout index 8e238a509d2..5bca83e87f8 100644 --- a/tests/ui/deriving/deriving-all-codegen.stdout +++ b/tests/ui/deriving/deriving-all-codegen.stdout @@ -98,7 +98,7 @@ impl ::core::marker::Copy for Point { } impl ::core::fmt::Debug for Point { fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { ::core::fmt::Formatter::debug_struct_field2_finish(f, "Point", "x", - &&self.x, "y", &&self.y) + &self.x, "y", &&self.y) } } #[automatically_derived] @@ -183,7 +183,7 @@ impl ::core::marker::Copy for PackedPoint { } impl ::core::fmt::Debug for PackedPoint { fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { ::core::fmt::Formatter::debug_struct_field2_finish(f, "PackedPoint", - "x", &&{ self.x }, "y", &&{ self.y }) + "x", &{ self.x }, "y", &&{ self.y }) } } #[automatically_derived] @@ -277,8 +277,8 @@ impl ::core::fmt::Debug for Big { let names: &'static _ = &["b1", "b2", "b3", "b4", "b5", "b6", "b7", "b8"]; let values: &[&dyn ::core::fmt::Debug] = - &[&&self.b1, &&self.b2, &&self.b3, &&self.b4, &&self.b5, - &&self.b6, &&self.b7, &&self.b8]; + &[&self.b1, &self.b2, &self.b3, &self.b4, &self.b5, &self.b6, + &self.b7, &&self.b8]; ::core::fmt::Formatter::debug_struct_fields_finish(f, "Big", names, values) } @@ -565,7 +565,7 @@ impl ::core::fmt::Debug for Generic where T::A: ::core::fmt::Debug { fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { ::core::fmt::Formatter::debug_struct_field3_finish(f, "Generic", "t", - &&self.t, "ta", &&self.ta, "u", &&self.u) + &self.t, "ta", &self.ta, "u", &&self.u) } } #[automatically_derived] @@ -682,7 +682,7 @@ impl ::core::fmt::Result { ::core::fmt::Formatter::debug_tuple_field3_finish(f, "PackedGeneric", - &&{ self.0 }, &&{ self.1 }, &&{ self.2 }) + &{ self.0 }, &{ self.1 }, &&{ self.2 }) } } #[automatically_derived] @@ -1084,7 +1084,7 @@ impl ::core::fmt::Debug for Mixed { &__self_0), Mixed::S { d1: __self_0, d2: __self_1 } => ::core::fmt::Formatter::debug_struct_field2_finish(f, "S", - "d1", &__self_0, "d2", &__self_1), + "d1", __self_0, "d2", &__self_1), } } }