about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMartin Nordholts <martin.nordholts@codetale.se>2025-08-28 20:11:07 +0200
committerMartin Nordholts <martin.nordholts@codetale.se>2025-08-28 20:37:09 +0200
commit4edfeb2f60e4c9f871117965070946ff566810d0 (patch)
tree6ad47167556f7d1119d27bdc45447fbbef8f6bff
parent1f7dcc878d73c45cc40018aac6e5c767446df110 (diff)
downloadrust-4edfeb2f60e4c9f871117965070946ff566810d0.tar.gz
rust-4edfeb2f60e4c9f871117965070946ff566810d0.zip
compiler: Include span of too huge enum with -Cdebuginfo=2
We have a ui test to ensure we emit an error if we encounter too big
enums. Before this fix, compiling the test with `-Cdebuginfo=2` would
not include the span of the instantiation site, because the error is
then emitted from a different code path that does not include the span.

Propagate the span to the error also in the debuginfo case, so the test
passes regardless of debuginfo level.
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs14
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs5
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/mod.rs6
-rw-r--r--tests/ui/limits/huge-enum.full-debuginfo.stderr (renamed from tests/ui/limits/huge-enum.stderr)2
-rw-r--r--tests/ui/limits/huge-enum.no-debuginfo.stderr8
-rw-r--r--tests/ui/limits/huge-enum.rs8
6 files changed, 33 insertions, 10 deletions
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
index 0e9dbfba658..caa3369f413 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
@@ -19,7 +19,9 @@ use rustc_middle::ty::{
     self, AdtKind, CoroutineArgsExt, ExistentialTraitRef, Instance, Ty, TyCtxt, Visibility,
 };
 use rustc_session::config::{self, DebugInfo, Lto};
-use rustc_span::{DUMMY_SP, FileName, FileNameDisplayPreference, SourceFile, Symbol, hygiene};
+use rustc_span::{
+    DUMMY_SP, FileName, FileNameDisplayPreference, SourceFile, Span, Symbol, hygiene,
+};
 use rustc_symbol_mangling::typeid_for_trait_ref;
 use rustc_target::spec::DebuginfoKind;
 use smallvec::smallvec;
@@ -423,6 +425,14 @@ fn build_slice_type_di_node<'ll, 'tcx>(
 /// This function will look up the debuginfo node in the TypeMap. If it can't find it, it
 /// will create the node by dispatching to the corresponding `build_*_di_node()` function.
 pub(crate) fn type_di_node<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> &'ll DIType {
+    spanned_type_di_node(cx, t, DUMMY_SP)
+}
+
+pub(crate) fn spanned_type_di_node<'ll, 'tcx>(
+    cx: &CodegenCx<'ll, 'tcx>,
+    t: Ty<'tcx>,
+    span: Span,
+) -> &'ll DIType {
     let unique_type_id = UniqueTypeId::for_ty(cx.tcx, t);
 
     if let Some(existing_di_node) = debug_context(cx).type_map.di_node_for_unique_id(unique_type_id)
@@ -460,7 +470,7 @@ pub(crate) fn type_di_node<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) ->
         ty::Adt(def, ..) => match def.adt_kind() {
             AdtKind::Struct => build_struct_type_di_node(cx, unique_type_id),
             AdtKind::Union => build_union_type_di_node(cx, unique_type_id),
-            AdtKind::Enum => enums::build_enum_type_di_node(cx, unique_type_id),
+            AdtKind::Enum => enums::build_enum_type_di_node(cx, unique_type_id, span),
         },
         ty::Tuple(_) => build_tuple_type_di_node(cx, unique_type_id),
         _ => bug!("debuginfo: unexpected type in type_di_node(): {:?}", t),
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs
index 7c701926d2c..caff3586079 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs
@@ -10,7 +10,7 @@ use rustc_middle::bug;
 use rustc_middle::mir::CoroutineLayout;
 use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
 use rustc_middle::ty::{self, AdtDef, CoroutineArgs, CoroutineArgsExt, Ty, VariantDef};
-use rustc_span::Symbol;
+use rustc_span::{Span, Symbol};
 
 use super::type_map::{DINodeCreationResult, UniqueTypeId};
 use super::{SmallVec, size_and_align_of};
@@ -30,13 +30,14 @@ mod native;
 pub(super) fn build_enum_type_di_node<'ll, 'tcx>(
     cx: &CodegenCx<'ll, 'tcx>,
     unique_type_id: UniqueTypeId<'tcx>,
+    span: Span,
 ) -> DINodeCreationResult<'ll> {
     let enum_type = unique_type_id.expect_ty();
     let &ty::Adt(enum_adt_def, _) = enum_type.kind() else {
         bug!("build_enum_type_di_node() called with non-enum type: `{:?}`", enum_type)
     };
 
-    let enum_type_and_layout = cx.layout_of(enum_type);
+    let enum_type_and_layout = cx.spanned_layout_of(enum_type, span);
 
     if wants_c_like_enum_debuginfo(cx.tcx, enum_type_and_layout) {
         return build_c_style_enum_di_node(cx, enum_adt_def, enum_type_and_layout);
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
index 2c3a84499ac..79334f7f9fe 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
@@ -28,7 +28,9 @@ use rustc_target::spec::DebuginfoKind;
 use smallvec::SmallVec;
 use tracing::debug;
 
-use self::metadata::{UNKNOWN_COLUMN_NUMBER, UNKNOWN_LINE_NUMBER, file_metadata, type_di_node};
+use self::metadata::{
+    UNKNOWN_COLUMN_NUMBER, UNKNOWN_LINE_NUMBER, file_metadata, spanned_type_di_node, type_di_node,
+};
 use self::namespace::mangled_name_of_instance;
 use self::utils::{DIB, create_DIArray, is_node_local_to_unit};
 use crate::builder::Builder;
@@ -626,7 +628,7 @@ impl<'ll, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
         let loc = self.lookup_debug_loc(span.lo());
         let file_metadata = file_metadata(self, &loc.file);
 
-        let type_metadata = type_di_node(self, variable_type);
+        let type_metadata = spanned_type_di_node(self, variable_type, span);
 
         let (argument_index, dwarf_tag) = match variable_kind {
             ArgumentVariable(index) => (index as c_uint, DW_TAG_arg_variable),
diff --git a/tests/ui/limits/huge-enum.stderr b/tests/ui/limits/huge-enum.full-debuginfo.stderr
index 5b97a2104a3..4b179d59e5f 100644
--- a/tests/ui/limits/huge-enum.stderr
+++ b/tests/ui/limits/huge-enum.full-debuginfo.stderr
@@ -1,5 +1,5 @@
 error: values of the type `Option<TYPE>` are too big for the target architecture
-  --> $DIR/huge-enum.rs:15:9
+  --> $DIR/huge-enum.rs:17:9
    |
 LL |     let big: BIG = None;
    |         ^^^
diff --git a/tests/ui/limits/huge-enum.no-debuginfo.stderr b/tests/ui/limits/huge-enum.no-debuginfo.stderr
new file mode 100644
index 00000000000..4b179d59e5f
--- /dev/null
+++ b/tests/ui/limits/huge-enum.no-debuginfo.stderr
@@ -0,0 +1,8 @@
+error: values of the type `Option<TYPE>` are too big for the target architecture
+  --> $DIR/huge-enum.rs:17:9
+   |
+LL |     let big: BIG = None;
+   |         ^^^
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/limits/huge-enum.rs b/tests/ui/limits/huge-enum.rs
index 6d5b86411f3..9395bee9765 100644
--- a/tests/ui/limits/huge-enum.rs
+++ b/tests/ui/limits/huge-enum.rs
@@ -1,9 +1,11 @@
+// FIXME(#61117): Remove revisions once x86_64-gnu-debug CI job sets rust.debuginfo-level-tests=2
+// NOTE: The .stderr for both revisions shall be identical.
+//@ revisions: no-debuginfo full-debuginfo
 //@ build-fail
 //@ normalize-stderr: "std::option::Option<\[u32; \d+\]>" -> "TYPE"
 //@ normalize-stderr: "\[u32; \d+\]" -> "TYPE"
-
-// FIXME(#61117): Respect debuginfo-level-tests, do not force debuginfo-level=0
-//@ compile-flags: -Cdebuginfo=0
+//@[no-debuginfo] compile-flags: -Cdebuginfo=0
+//@[full-debuginfo] compile-flags: -Cdebuginfo=2
 
 #[cfg(target_pointer_width = "32")]
 type BIG = Option<[u32; (1<<29)-1]>;