diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs index 4b1563ca3c97f..a67414036dc23 100644 --- a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs +++ b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs @@ -74,9 +74,30 @@ fn push_debuginfo_type_name<'tcx>( ty::Float(float_ty) => output.push_str(float_ty.name_str()), ty::Foreign(def_id) => push_item_name(tcx, def_id, qualified, output), ty::Adt(def, substs) => { - let ty_and_layout = tcx.layout_of(ParamEnv::reveal_all().and(t)).expect("layout error"); + // `layout_for_cpp_like_fallback` will be `Some` if we want to use the fallback encoding. + let layout_for_cpp_like_fallback = if cpp_like_debuginfo && def.is_enum() { + match tcx.layout_of(ParamEnv::reveal_all().and(t)) { + Ok(layout) => { + if !wants_c_like_enum_debuginfo(layout) { + Some(layout) + } else { + // This is a C-like enum so we don't want to use the fallback encoding + // for the name. + None + } + } + Err(e) => { + // Computing the layout can still fail here, e.g. if the target architecture + // cannot represent the type. See https://github.com/rust-lang/rust/issues/94961. + tcx.sess.fatal(&format!("{}", e)); + } + } + } else { + // We are not emitting cpp-like debuginfo or this isn't even an enum. + None + }; - if def.is_enum() && cpp_like_debuginfo && !wants_c_like_enum_debuginfo(ty_and_layout) { + if let Some(ty_and_layout) = layout_for_cpp_like_fallback { msvc_enum_fallback( tcx, ty_and_layout, diff --git a/src/test/ui/debuginfo/debuginfo-type-name-layout-ice-94961-1.rs b/src/test/ui/debuginfo/debuginfo-type-name-layout-ice-94961-1.rs new file mode 100644 index 0000000000000..78bda28485dce --- /dev/null +++ b/src/test/ui/debuginfo/debuginfo-type-name-layout-ice-94961-1.rs @@ -0,0 +1,16 @@ +// Make sure the compiler does not ICE when trying to generate the debuginfo name of a type that +// causes a layout error. See https://github.com/rust-lang/rust/issues/94961. + +// compile-flags:-C debuginfo=2 +// build-fail +// error-pattern: too big for the current architecture +// normalize-stderr-64bit "18446744073709551615" -> "SIZE" +// normalize-stderr-32bit "4294967295" -> "SIZE" + +#![crate_type = "rlib"] + +pub struct Foo([T; usize::MAX]); + +pub fn foo() -> usize { + std::mem::size_of::>() +} diff --git a/src/test/ui/debuginfo/debuginfo-type-name-layout-ice-94961-1.stderr b/src/test/ui/debuginfo/debuginfo-type-name-layout-ice-94961-1.stderr new file mode 100644 index 0000000000000..851dca84c3dc0 --- /dev/null +++ b/src/test/ui/debuginfo/debuginfo-type-name-layout-ice-94961-1.stderr @@ -0,0 +1,4 @@ +error: values of the type `[u8; SIZE]` are too big for the current architecture + +error: aborting due to previous error + diff --git a/src/test/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.rs b/src/test/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.rs new file mode 100644 index 0000000000000..fdc088dc0f9a5 --- /dev/null +++ b/src/test/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.rs @@ -0,0 +1,20 @@ +// Make sure the compiler does not ICE when trying to generate the debuginfo name of a type that +// causes a layout error. +// This version of the test already ICE'd before the commit that introduce the ICE described in +// https://github.com/rust-lang/rust/issues/94961. + +// compile-flags:-C debuginfo=2 +// build-fail +// error-pattern: too big for the current architecture +// normalize-stderr-64bit "18446744073709551615" -> "SIZE" +// normalize-stderr-32bit "4294967295" -> "SIZE" + +#![crate_type = "rlib"] + +pub enum Foo { + Bar([T; usize::MAX]), +} + +pub fn foo() -> usize { + std::mem::size_of::>() +} diff --git a/src/test/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.stderr b/src/test/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.stderr new file mode 100644 index 0000000000000..851dca84c3dc0 --- /dev/null +++ b/src/test/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.stderr @@ -0,0 +1,4 @@ +error: values of the type `[u8; SIZE]` are too big for the current architecture + +error: aborting due to previous error +