Use a delayed bug for this layout ICE

Fixes 144501
This commit is contained in:
Scott McMurray 2025-11-28 14:49:42 -08:00
parent 07bdbaedc6
commit 673be1b82a
5 changed files with 118 additions and 5 deletions

View file

@ -1366,7 +1366,7 @@ impl<'a> DiagCtxtHandle<'a> {
self.create_err(err).emit()
}
/// Ensures that an error is printed. See `Level::DelayedBug`.
/// Ensures that an error is printed. See [`Level::DelayedBug`].
//
// No `#[rustc_lint_diagnostics]` and no `impl Into<DiagMessage>` because bug messages aren't
// user-facing.

View file

@ -281,10 +281,16 @@ pub(super) fn layout_sanity_check<'tcx>(cx: &LayoutCx<'tcx>, layout: &TyAndLayou
}
// Ensure that for niche encoded tags the discriminant coincides with the variant index.
assert_eq!(
layout.ty.discriminant_for_variant(tcx, idx).unwrap().val,
u128::from(idx.as_u32()),
);
let val = layout.ty.discriminant_for_variant(tcx, idx).unwrap().val;
if val != u128::from(idx.as_u32()) {
let adt_def = layout.ty.ty_adt_def().unwrap();
cx.tcx().dcx().span_delayed_bug(
cx.tcx().def_span(adt_def.did()),
format!(
"variant {idx:?} has discriminant {val:?} in niche-encoded type"
),
);
}
}
}
for variant in variants.iter() {

View file

@ -0,0 +1,35 @@
error[E0732]: `#[repr(inttype)]` must be specified for enums with explicit discriminants and non-unit variants
--> $DIR/invalid-niche-discriminant.rs:11:1
|
LL | enum E {
| ^^^^^^
...
LL | S0 {
| -- non-unit discriminant declared here
...
LL | Bar = {
| ___________-
LL | | let x = 1;
LL | | 3
LL | | },
| |_____- explicit discriminant specified here
error[E0599]: no variant named `S1` found for enum `E`
--> $DIR/invalid-niche-discriminant.rs:23:18
|
LL | enum E {
| ------ variant `S1` not found here
...
LL | static C: E = E::S1 { u: 23 };
| ^^
|
help: there is a variant with a similar name
|
LL - static C: E = E::S1 { u: 23 };
LL + static C: E = E::S0 { u: 23 };
|
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0599, E0732.
For more information about an error, try `rustc --explain E0599`.

View file

@ -0,0 +1,25 @@
//@ needs-rustc-debug-assertions
//@ revisions: normal with_delayed
//@ [with_delayed] compile-flags: -Z eagerly-emit-delayed-bugs
#![crate_type = "lib"]
// Repro for <https://github.com/rust-lang/rust/issues/144501>
// which ICEd because the calculated layout is invalid
// but which we needn't care about as the discriminant already was.
enum E {
//~^ ERROR must be specified
//[with_delayed]~| ERROR variant 1 has discriminant 3
S0 {
s: String,
},
Bar = {
let x = 1;
3
},
}
static C: E = E::S1 { u: 23 };
//~^ ERROR no variant named
//[with_delayed]~| ERROR but no error emitted

View file

@ -0,0 +1,47 @@
error[E0732]: `#[repr(inttype)]` must be specified for enums with explicit discriminants and non-unit variants
--> $DIR/invalid-niche-discriminant.rs:11:1
|
LL | enum E {
| ^^^^^^
...
LL | S0 {
| -- non-unit discriminant declared here
...
LL | Bar = {
| ___________-
LL | | let x = 1;
LL | | 3
LL | | },
| |_____- explicit discriminant specified here
error: variant 1 has discriminant 3 in niche-encoded type
--> $DIR/invalid-niche-discriminant.rs:11:1
|
LL | enum E {
| ^^^^^^
error[E0599]: no variant named `S1` found for enum `E`
--> $DIR/invalid-niche-discriminant.rs:23:18
|
LL | enum E {
| ------ variant `S1` not found here
...
LL | static C: E = E::S1 { u: 23 };
| ^^
|
help: there is a variant with a similar name
|
LL - static C: E = E::S1 { u: 23 };
LL + static C: E = E::S0 { u: 23 };
|
error: `Res::Err` but no error emitted
--> $DIR/invalid-niche-discriminant.rs:23:15
|
LL | static C: E = E::S1 { u: 23 };
| ^^^^^
error: aborting due to 4 previous errors
Some errors have detailed explanations: E0599, E0732.
For more information about an error, try `rustc --explain E0599`.