Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Consider more erroneous layouts as LayoutError::ReferencesError to suppress spurious errors #135264

Merged
merged 1 commit into from
Jan 15, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 20 additions & 12 deletions compiler/rustc_ty_utils/src/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,21 +105,27 @@ fn map_error<'tcx>(
// See `tests/ui/layout/trivial-bounds-sized.rs` for an example.
assert!(field.layout.is_unsized(), "invalid layout error {err:#?}");
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:#?}"
));
LayoutError::ReferencesError(guar)
} else {
LayoutError::Unknown(ty)
}
LayoutError::Unknown(ty)
}
LayoutCalculatorError::EmptyUnion => {
// This is always a compile error.
compiler-errors marked this conversation as resolved.
Show resolved Hide resolved
cx.tcx().dcx().delayed_bug(format!("computed layout of empty union: {ty:?}"));
LayoutError::Unknown(ty)
let guar =
cx.tcx().dcx().delayed_bug(format!("computed layout of empty union: {ty:?}"));
LayoutError::ReferencesError(guar)
}
LayoutCalculatorError::ReprConflict => {
// 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:?}"));
LayoutError::Unknown(ty)
let guar = cx
.tcx()
.dcx()
.delayed_bug(format!("computed impossible repr (packed enum?): {ty:?}"));
LayoutError::ReferencesError(guar)
}
};
error(cx, err)
Expand Down Expand Up @@ -432,8 +438,10 @@ fn layout_of_uncached<'tcx>(
ty::Adt(def, args) if def.repr().simd() => {
if !def.is_struct() {
// Should have yielded E0517 by now.
tcx.dcx().delayed_bug("#[repr(simd)] was applied to an ADT that is not a struct");
return Err(error(cx, LayoutError::Unknown(ty)));
let guar = tcx
.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;
Expand All @@ -459,10 +467,10 @@ fn layout_of_uncached<'tcx>(
// (should be caught by typeck)
for fi in fields {
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",
);
return Err(error(cx, LayoutError::Unknown(ty)));
return Err(error(cx, LayoutError::ReferencesError(guar)));
}
}

Expand Down Expand Up @@ -567,11 +575,11 @@ fn layout_of_uncached<'tcx>(

if def.is_union() {
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()),
"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(
Expand Down
37 changes: 37 additions & 0 deletions tests/ui/enum-discriminant/eval-error.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 51 additions & 0 deletions tests/ui/enum-discriminant/eval-error.stderr
Original file line number Diff line number Diff line change
@@ -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`.
1 change: 0 additions & 1 deletion tests/ui/layout/base-layout-is-sized-ice-123078.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ struct S {
}

const C: S = unsafe { std::mem::transmute(()) };
//~^ ERROR cannot transmute between types of different sizes, or dependently-sized types
const _: [(); {
C;
0
Expand Down
14 changes: 2 additions & 12 deletions tests/ui/layout/base-layout-is-sized-ice-123078.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,6 @@ help: the `Box` type always has a statically known size and allocates its conten
LL | a: Box<[u8]>,
| ++++ +

error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
--> $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
error: aborting due to 1 previous error

Some errors have detailed explanations: E0277, E0512.
For more information about an error, try `rustc --explain E0277`.
For more information about this error, try `rustc --explain E0277`.
2 changes: 1 addition & 1 deletion tests/ui/layout/debug.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -590,7 +590,7 @@ LL | type Impossible = (str, str);
= help: the trait `Sized` is not implemented for `str`
= 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
|
LL | union EmptyUnion {}
Expand Down
Loading