diff --git a/compiler/rustc_builtin_macros/src/deriving/debug.rs b/compiler/rustc_builtin_macros/src/deriving/debug.rs index 809f9838d20be..db21a572f612f 100644 --- a/compiler/rustc_builtin_macros/src/deriving/debug.rs +++ b/compiler/rustc_builtin_macros/src/deriving/debug.rs @@ -197,15 +197,18 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_> } /// Special case for enums with no fields. Builds: +/// /// ```text -/// impl ::core::fmt::Debug for A { +/// impl ::core::fmt::Debug for Fieldless { /// fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { -/// ::core::fmt::Formatter::write_str(f, -/// match self { -/// A::A => "A", -/// A::B() => "B", -/// A::C {} => "C", -/// }) +/// ::core::fmt::Formatter::write_str( +/// f, +/// const { ["A", "B", "C"] }[match self { +/// Fieldless::A => 0usize, +/// Fieldless::B => 1usize, +/// Fieldless::C => 2usize, +/// }], +/// ) /// } /// } /// ``` @@ -216,10 +219,14 @@ fn show_fieldless_enum( substr: &Substructure<'_>, ) -> BlockOrExpr { let fmt = substr.nonselflike_args[0].clone(); + + let strs = def.variants.iter().map(|v| cx.expr_str(span, v.ident.name)).collect(); + let array = cx.expr_const_block(span, cx.block_expr(cx.expr_array(span, strs))); let arms = def .variants .iter() - .map(|v| { + .enumerate() + .map(|(i, v)| { let variant_path = cx.path(span, vec![substr.type_ident, v.ident]); let pat = match &v.data { ast::VariantData::Tuple(fields, _) => { @@ -232,10 +239,12 @@ fn show_fieldless_enum( } ast::VariantData::Unit(_) => cx.pat_path(span, variant_path), }; - cx.arm(span, pat, cx.expr_str(span, v.ident.name)) + cx.arm(span, pat, cx.expr_usize(span, i)) }) .collect::>(); - let name = cx.expr_match(span, cx.expr_self(span), arms); + let match_expr = cx.expr_match(span, cx.expr_self(span), arms); + let name = cx.expr_index(span, array, match_expr); + let fn_path_write_str = cx.std_path(&[sym::fmt, sym::Formatter, sym::write_str]); BlockOrExpr::new_expr(cx.expr_call_global(span, fn_path_write_str, thin_vec![fmt, name])) } diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs index 264f30fb10a12..fb6c33f35614c 100644 --- a/compiler/rustc_expand/src/build.rs +++ b/compiler/rustc_expand/src/build.rs @@ -250,6 +250,7 @@ impl<'a> ExtCtxt<'a> { pub fn expr_ident(&self, span: Span, id: Ident) -> P { self.expr_path(self.path_ident(span, id)) } + pub fn expr_self(&self, span: Span) -> P { self.expr_ident(span, Ident::with_dummy_span(kw::SelfLower)) } @@ -276,6 +277,10 @@ impl<'a> ExtCtxt<'a> { self.expr(sp, ast::ExprKind::AddrOf(ast::BorrowKind::Ref, ast::Mutability::Not, e)) } + pub fn expr_index(&self, span: Span, val: P, index: P) -> P { + self.expr(span, ast::ExprKind::Index(val, index)) + } + pub fn expr_paren(&self, sp: Span, e: P) -> P { self.expr(sp, ast::ExprKind::Paren(e)) } @@ -288,6 +293,7 @@ impl<'a> ExtCtxt<'a> { ) -> P { self.expr(span, ast::ExprKind::Call(expr, args)) } + pub fn expr_call_ident( &self, span: Span, @@ -296,6 +302,7 @@ impl<'a> ExtCtxt<'a> { ) -> P { self.expr(span, ast::ExprKind::Call(self.expr_ident(span, id), args)) } + pub fn expr_call_global( &self, sp: Span, @@ -305,9 +312,19 @@ impl<'a> ExtCtxt<'a> { let pathexpr = self.expr_path(self.path_global(sp, fn_path)); self.expr_call(sp, pathexpr, args) } + pub fn expr_block(&self, b: P) -> P { self.expr(b.span, ast::ExprKind::Block(b, None)) } + + pub fn expr_const(&self, span: Span, kind: ast::ExprKind) -> P { + self.expr(span, ast::ExprKind::ConstBlock(self.anon_const(span, kind))) + } + + pub fn expr_const_block(&self, span: Span, b: P) -> P { + self.expr_const(span, ast::ExprKind::Block(b, None)) + } + pub fn field_imm(&self, span: Span, ident: Ident, e: P) -> ast::ExprField { ast::ExprField { ident: ident.with_span_pos(span), @@ -319,6 +336,7 @@ impl<'a> ExtCtxt<'a> { is_placeholder: false, } } + pub fn expr_struct( &self, span: Span, @@ -335,6 +353,7 @@ impl<'a> ExtCtxt<'a> { })), ) } + pub fn expr_struct_ident( &self, span: Span, diff --git a/tests/ui/deriving/deriving-all-codegen.stdout b/tests/ui/deriving/deriving-all-codegen.stdout index 6bfc859bfe807..522c0d1a8762d 100644 --- a/tests/ui/deriving/deriving-all-codegen.stdout +++ b/tests/ui/deriving/deriving-all-codegen.stdout @@ -997,11 +997,13 @@ impl ::core::marker::Copy for Fieldless { } impl ::core::fmt::Debug for Fieldless { fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { ::core::fmt::Formatter::write_str(f, - match self { - Fieldless::A => "A", - Fieldless::B => "B", - Fieldless::C => "C", - }) + const { + ["A", "B", "C"] + }[match self { + Fieldless::A => 0usize, + Fieldless::B => 1usize, + Fieldless::C => 2usize, + }]) } } #[automatically_derived]