Consider more erroneous layouts as LayoutError::ReferencesError to suppress spurious errors
This commit is contained in:
parent
8c39ce5b4f
commit
b89a6e4932
6 changed files with 111 additions and 26 deletions
|
@ -105,21 +105,27 @@ fn map_error<'tcx>(
|
||||||
// See `tests/ui/layout/trivial-bounds-sized.rs` for an example.
|
// See `tests/ui/layout/trivial-bounds-sized.rs` for an example.
|
||||||
assert!(field.layout.is_unsized(), "invalid layout error {err:#?}");
|
assert!(field.layout.is_unsized(), "invalid layout error {err:#?}");
|
||||||
if !field.ty.is_sized(cx.tcx(), cx.typing_env) {
|
if !field.ty.is_sized(cx.tcx(), cx.typing_env) {
|
||||||
cx.tcx().dcx().delayed_bug(format!(
|
let guar = cx.tcx().dcx().delayed_bug(format!(
|
||||||
"encountered unexpected unsized field in layout of {ty:?}: {field:#?}"
|
"encountered unexpected unsized field in layout of {ty:?}: {field:#?}"
|
||||||
));
|
));
|
||||||
|
LayoutError::ReferencesError(guar)
|
||||||
|
} else {
|
||||||
|
LayoutError::Unknown(ty)
|
||||||
}
|
}
|
||||||
LayoutError::Unknown(ty)
|
|
||||||
}
|
}
|
||||||
LayoutCalculatorError::EmptyUnion => {
|
LayoutCalculatorError::EmptyUnion => {
|
||||||
// This is always a compile error.
|
// This is always a compile error.
|
||||||
cx.tcx().dcx().delayed_bug(format!("computed layout of empty union: {ty:?}"));
|
let guar =
|
||||||
LayoutError::Unknown(ty)
|
cx.tcx().dcx().delayed_bug(format!("computed layout of empty union: {ty:?}"));
|
||||||
|
LayoutError::ReferencesError(guar)
|
||||||
}
|
}
|
||||||
LayoutCalculatorError::ReprConflict => {
|
LayoutCalculatorError::ReprConflict => {
|
||||||
// packed enums are the only known trigger of this, but others might arise
|
// packed enums are the only known trigger of this, but others might arise
|
||||||
cx.tcx().dcx().delayed_bug(format!("computed impossible repr (packed enum?): {ty:?}"));
|
let guar = cx
|
||||||
LayoutError::Unknown(ty)
|
.tcx()
|
||||||
|
.dcx()
|
||||||
|
.delayed_bug(format!("computed impossible repr (packed enum?): {ty:?}"));
|
||||||
|
LayoutError::ReferencesError(guar)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
error(cx, err)
|
error(cx, err)
|
||||||
|
@ -432,8 +438,10 @@ fn layout_of_uncached<'tcx>(
|
||||||
ty::Adt(def, args) if def.repr().simd() => {
|
ty::Adt(def, args) if def.repr().simd() => {
|
||||||
if !def.is_struct() {
|
if !def.is_struct() {
|
||||||
// Should have yielded E0517 by now.
|
// Should have yielded E0517 by now.
|
||||||
tcx.dcx().delayed_bug("#[repr(simd)] was applied to an ADT that is not a struct");
|
let guar = tcx
|
||||||
return Err(error(cx, LayoutError::Unknown(ty)));
|
.dcx()
|
||||||
|
.delayed_bug("#[repr(simd)] was applied to an ADT that is not a struct");
|
||||||
|
return Err(error(cx, LayoutError::ReferencesError(guar)));
|
||||||
}
|
}
|
||||||
|
|
||||||
let fields = &def.non_enum_variant().fields;
|
let fields = &def.non_enum_variant().fields;
|
||||||
|
@ -459,10 +467,10 @@ fn layout_of_uncached<'tcx>(
|
||||||
// (should be caught by typeck)
|
// (should be caught by typeck)
|
||||||
for fi in fields {
|
for fi in fields {
|
||||||
if fi.ty(tcx, args) != f0_ty {
|
if fi.ty(tcx, args) != f0_ty {
|
||||||
tcx.dcx().delayed_bug(
|
let guar = tcx.dcx().delayed_bug(
|
||||||
"#[repr(simd)] was applied to an ADT with heterogeneous field type",
|
"#[repr(simd)] was applied to an ADT with heterogeneous field type",
|
||||||
);
|
);
|
||||||
return Err(error(cx, LayoutError::Unknown(ty)));
|
return Err(error(cx, LayoutError::ReferencesError(guar)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -567,11 +575,11 @@ fn layout_of_uncached<'tcx>(
|
||||||
|
|
||||||
if def.is_union() {
|
if def.is_union() {
|
||||||
if def.repr().pack.is_some() && def.repr().align.is_some() {
|
if def.repr().pack.is_some() && def.repr().align.is_some() {
|
||||||
tcx.dcx().span_delayed_bug(
|
let guar = tcx.dcx().span_delayed_bug(
|
||||||
tcx.def_span(def.did()),
|
tcx.def_span(def.did()),
|
||||||
"union cannot be packed and aligned",
|
"union cannot be packed and aligned",
|
||||||
);
|
);
|
||||||
return Err(error(cx, LayoutError::Unknown(ty)));
|
return Err(error(cx, LayoutError::ReferencesError(guar)));
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ok(tcx.mk_layout(
|
return Ok(tcx.mk_layout(
|
||||||
|
|
37
tests/ui/enum-discriminant/eval-error.rs
Normal file
37
tests/ui/enum-discriminant/eval-error.rs
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
union Foo {
|
||||||
|
a: str,
|
||||||
|
//~^ ERROR the size for values of type `str` cannot be known at compilation time
|
||||||
|
//~| ERROR field must implement `Copy` or be wrapped in `ManuallyDrop<...>`
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Bar {
|
||||||
|
Boo = {
|
||||||
|
let _: Option<Foo> = None;
|
||||||
|
0
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
union Foo2 {}
|
||||||
|
//~^ ERROR unions cannot have zero fields
|
||||||
|
|
||||||
|
enum Bar2 {
|
||||||
|
Boo = {
|
||||||
|
let _: Option<Foo2> = None;
|
||||||
|
0
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(u8, packed)]
|
||||||
|
//~^ ERROR attribute should be applied to a struct or union
|
||||||
|
enum Foo3 {
|
||||||
|
A
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Bar3 {
|
||||||
|
Boo = {
|
||||||
|
let _: Option<Foo3> = None;
|
||||||
|
0
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
51
tests/ui/enum-discriminant/eval-error.stderr
Normal file
51
tests/ui/enum-discriminant/eval-error.stderr
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
error: unions cannot have zero fields
|
||||||
|
--> $DIR/eval-error.rs:14:1
|
||||||
|
|
|
||||||
|
LL | union Foo2 {}
|
||||||
|
| ^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0517]: attribute should be applied to a struct or union
|
||||||
|
--> $DIR/eval-error.rs:24:12
|
||||||
|
|
|
||||||
|
LL | #[repr(u8, packed)]
|
||||||
|
| ^^^^^^
|
||||||
|
LL |
|
||||||
|
LL | / enum Foo3 {
|
||||||
|
LL | | A
|
||||||
|
LL | | }
|
||||||
|
| |_- not a struct or union
|
||||||
|
|
||||||
|
error[E0277]: the size for values of type `str` cannot be known at compilation time
|
||||||
|
--> $DIR/eval-error.rs:2:8
|
||||||
|
|
|
||||||
|
LL | a: str,
|
||||||
|
| ^^^ doesn't have a size known at compile-time
|
||||||
|
|
|
||||||
|
= help: the trait `Sized` is not implemented for `str`
|
||||||
|
= note: no field of a union may have a dynamically sized type
|
||||||
|
= help: change the field's type to have a statically known size
|
||||||
|
help: borrowed types always have a statically known size
|
||||||
|
|
|
||||||
|
LL | a: &str,
|
||||||
|
| +
|
||||||
|
help: the `Box` type always has a statically known size and allocates its contents in the heap
|
||||||
|
|
|
||||||
|
LL | a: Box<str>,
|
||||||
|
| ++++ +
|
||||||
|
|
||||||
|
error[E0740]: field must implement `Copy` or be wrapped in `ManuallyDrop<...>` to be used in a union
|
||||||
|
--> $DIR/eval-error.rs:2:5
|
||||||
|
|
|
||||||
|
LL | a: str,
|
||||||
|
| ^^^^^^
|
||||||
|
|
|
||||||
|
= note: union fields must not have drop side-effects, which is currently enforced via either `Copy` or `ManuallyDrop<...>`
|
||||||
|
help: wrap the field type in `ManuallyDrop<...>`
|
||||||
|
|
|
||||||
|
LL | a: std::mem::ManuallyDrop<str>,
|
||||||
|
| +++++++++++++++++++++++ +
|
||||||
|
|
||||||
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
|
Some errors have detailed explanations: E0277, E0517, E0740.
|
||||||
|
For more information about an error, try `rustc --explain E0277`.
|
|
@ -8,7 +8,6 @@ struct S {
|
||||||
}
|
}
|
||||||
|
|
||||||
const C: S = unsafe { std::mem::transmute(()) };
|
const C: S = unsafe { std::mem::transmute(()) };
|
||||||
//~^ ERROR cannot transmute between types of different sizes, or dependently-sized types
|
|
||||||
const _: [(); {
|
const _: [(); {
|
||||||
C;
|
C;
|
||||||
0
|
0
|
||||||
|
|
|
@ -16,16 +16,6 @@ help: the `Box` type always has a statically known size and allocates its conten
|
||||||
LL | a: Box<[u8]>,
|
LL | a: Box<[u8]>,
|
||||||
| ++++ +
|
| ++++ +
|
||||||
|
|
||||||
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
|
error: aborting due to 1 previous error
|
||||||
--> $DIR/base-layout-is-sized-ice-123078.rs:10:23
|
|
||||||
|
|
|
||||||
LL | const C: S = unsafe { std::mem::transmute(()) };
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: source type: `()` (0 bits)
|
|
||||||
= note: target type: `S` (size can vary because of [u8])
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
For more information about this error, try `rustc --explain E0277`.
|
||||||
|
|
||||||
Some errors have detailed explanations: E0277, E0512.
|
|
||||||
For more information about an error, try `rustc --explain E0277`.
|
|
||||||
|
|
|
@ -590,7 +590,7 @@ LL | type Impossible = (str, str);
|
||||||
= help: the trait `Sized` is not implemented for `str`
|
= help: the trait `Sized` is not implemented for `str`
|
||||||
= note: only the last element of a tuple may have a dynamically sized type
|
= note: only the last element of a tuple may have a dynamically sized type
|
||||||
|
|
||||||
error: the type `EmptyUnion` has an unknown layout
|
error: the type has an unknown layout
|
||||||
--> $DIR/debug.rs:83:1
|
--> $DIR/debug.rs:83:1
|
||||||
|
|
|
|
||||||
LL | union EmptyUnion {}
|
LL | union EmptyUnion {}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue