Use a delayed bug for this layout ICE
Fixes 144501
This commit is contained in:
parent
07bdbaedc6
commit
673be1b82a
5 changed files with 118 additions and 5 deletions
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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`.
|
||||
25
tests/ui/enum-discriminant/invalid-niche-discriminant.rs
Normal file
25
tests/ui/enum-discriminant/invalid-niche-discriminant.rs
Normal 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
|
||||
|
|
@ -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`.
|
||||
Loading…
Add table
Add a link
Reference in a new issue