diff --git a/compiler/rustc_builtin_macros/src/deriving/debug.rs b/compiler/rustc_builtin_macros/src/deriving/debug.rs index 14506f296bf95..ecf70da6d96c5 100644 --- a/compiler/rustc_builtin_macros/src/deriving/debug.rs +++ b/compiler/rustc_builtin_macros/src/deriving/debug.rs @@ -65,15 +65,29 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_> // We want to make sure we have the ctxt set so that we can use unstable methods let span = cx.with_def_site_ctxt(span); let name = cx.expr_lit(span, ast::LitKind::Str(ident.name, ast::StrStyle::Cooked)); + let fmt = substr.nonself_args[0].clone(); + + // Special fast path for unit variants. In the common case of an enum that is entirely unit + // variants (i.e. a C-like enum), this fast path allows LLVM to eliminate the entire switch in + // favor of a lookup table. + if let ast::VariantData::Unit(..) = vdata { + let fn_path_write_str = cx.std_path(&[sym::fmt, sym::Formatter, sym::write_str]); + let expr = cx.expr_call_global(span, fn_path_write_str, vec![fmt, name]); + let stmts = vec![cx.stmt_expr(expr)]; + let block = cx.block(span, stmts); + return cx.expr_block(block); + } + let builder = Ident::new(sym::debug_trait_builder, span); let builder_expr = cx.expr_ident(span, builder); - let fmt = substr.nonself_args[0].clone(); - let mut stmts = Vec::with_capacity(fields.len() + 2); let fn_path_finish; match vdata { - ast::VariantData::Tuple(..) | ast::VariantData::Unit(..) => { + ast::VariantData::Unit(..) => { + cx.span_bug(span, "unit variants should have been handled above"); + } + ast::VariantData::Tuple(..) => { // tuple struct/"normal" variant let fn_path_debug_tuple = cx.std_path(&[sym::fmt, sym::Formatter, sym::debug_tuple]); let expr = cx.expr_call_global(span, fn_path_debug_tuple, vec![fmt, name]); diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index d14feecbbdf1d..760357644a57b 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1417,6 +1417,7 @@ symbols! { wrapping_sub, wreg, write_bytes, + write_str, x87_reg, xer, xmm_reg,