Skip to content

Commit

Permalink
Rollup merge of rust-lang#135264 - compiler-errors:layout-propagate-e…
Browse files Browse the repository at this point in the history
…rrors, r=oli-obk

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

Fixes rust-lang#135208

r? oli-obk
  • Loading branch information
matthiaskrgr authored Jan 14, 2025
2 parents 5af7c9d + b89a6e4 commit 92a6c67
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 26 deletions.
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.
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

0 comments on commit 92a6c67

Please sign in to comment.