Skip to content

Commit 5a72651

Browse files
Consider more erroneous layouts as LayoutError::ReferencesError to suppress spurious errors
1 parent 6afee11 commit 5a72651

File tree

5 files changed

+62
-21
lines changed

5 files changed

+62
-21
lines changed

compiler/rustc_ty_utils/src/layout.rs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -105,11 +105,13 @@ fn map_error<'tcx>(
105105
// See `tests/ui/layout/trivial-bounds-sized.rs` for an example.
106106
assert!(field.layout.is_unsized(), "invalid layout error {err:#?}");
107107
if !field.ty.is_sized(cx.tcx(), cx.typing_env) {
108-
cx.tcx().dcx().delayed_bug(format!(
108+
let guar = cx.tcx().dcx().delayed_bug(format!(
109109
"encountered unexpected unsized field in layout of {ty:?}: {field:#?}"
110110
));
111+
LayoutError::ReferencesError(guar)
112+
} else {
113+
LayoutError::Unknown(ty)
111114
}
112-
LayoutError::Unknown(ty)
113115
}
114116
LayoutCalculatorError::EmptyUnion => {
115117
// This is always a compile error.
@@ -427,8 +429,10 @@ fn layout_of_uncached<'tcx>(
427429
ty::Adt(def, args) if def.repr().simd() => {
428430
if !def.is_struct() {
429431
// Should have yielded E0517 by now.
430-
tcx.dcx().delayed_bug("#[repr(simd)] was applied to an ADT that is not a struct");
431-
return Err(error(cx, LayoutError::Unknown(ty)));
432+
let guar = tcx
433+
.dcx()
434+
.delayed_bug("#[repr(simd)] was applied to an ADT that is not a struct");
435+
return Err(error(cx, LayoutError::ReferencesError(guar)));
432436
}
433437

434438
let fields = &def.non_enum_variant().fields;
@@ -454,10 +458,10 @@ fn layout_of_uncached<'tcx>(
454458
// (should be caught by typeck)
455459
for fi in fields {
456460
if fi.ty(tcx, args) != f0_ty {
457-
tcx.dcx().delayed_bug(
461+
let guar = tcx.dcx().delayed_bug(
458462
"#[repr(simd)] was applied to an ADT with heterogeneous field type",
459463
);
460-
return Err(error(cx, LayoutError::Unknown(ty)));
464+
return Err(error(cx, LayoutError::ReferencesError(guar)));
461465
}
462466
}
463467

@@ -561,11 +565,11 @@ fn layout_of_uncached<'tcx>(
561565

562566
if def.is_union() {
563567
if def.repr().pack.is_some() && def.repr().align.is_some() {
564-
tcx.dcx().span_delayed_bug(
568+
let guar = tcx.dcx().span_delayed_bug(
565569
tcx.def_span(def.did()),
566570
"union cannot be packed and aligned",
567571
);
568-
return Err(error(cx, LayoutError::Unknown(ty)));
572+
return Err(error(cx, LayoutError::ReferencesError(guar)));
569573
}
570574

571575
return Ok(tcx.mk_layout(
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
union Foo {
2+
a: str,
3+
//~^ ERROR the size for values of type `str` cannot be known at compilation time
4+
//~| ERROR field must implement `Copy` or be wrapped in `ManuallyDrop<...>`
5+
}
6+
7+
enum Bar {
8+
Boo = {
9+
let _: Option<Foo> = None;
10+
0
11+
},
12+
}
13+
14+
fn main() {}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
error[E0277]: the size for values of type `str` cannot be known at compilation time
2+
--> $DIR/eval-error.rs:2:8
3+
|
4+
LL | a: str,
5+
| ^^^ doesn't have a size known at compile-time
6+
|
7+
= help: the trait `Sized` is not implemented for `str`
8+
= note: no field of a union may have a dynamically sized type
9+
= help: change the field's type to have a statically known size
10+
help: borrowed types always have a statically known size
11+
|
12+
LL | a: &str,
13+
| +
14+
help: the `Box` type always has a statically known size and allocates its contents in the heap
15+
|
16+
LL | a: Box<str>,
17+
| ++++ +
18+
19+
error[E0740]: field must implement `Copy` or be wrapped in `ManuallyDrop<...>` to be used in a union
20+
--> $DIR/eval-error.rs:2:5
21+
|
22+
LL | a: str,
23+
| ^^^^^^
24+
|
25+
= note: union fields must not have drop side-effects, which is currently enforced via either `Copy` or `ManuallyDrop<...>`
26+
help: wrap the field type in `ManuallyDrop<...>`
27+
|
28+
LL | a: std::mem::ManuallyDrop<str>,
29+
| +++++++++++++++++++++++ +
30+
31+
error: aborting due to 2 previous errors
32+
33+
Some errors have detailed explanations: E0277, E0740.
34+
For more information about an error, try `rustc --explain E0277`.

tests/ui/layout/base-layout-is-sized-ice-123078.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ struct S {
88
}
99

1010
const C: S = unsafe { std::mem::transmute(()) };
11-
//~^ ERROR cannot transmute between types of different sizes, or dependently-sized types
1211
const _: [(); {
1312
C;
1413
0

tests/ui/layout/base-layout-is-sized-ice-123078.stderr

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,6 @@ help: the `Box` type always has a statically known size and allocates its conten
1616
LL | a: Box<[u8]>,
1717
| ++++ +
1818

19-
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
20-
--> $DIR/base-layout-is-sized-ice-123078.rs:10:23
21-
|
22-
LL | const C: S = unsafe { std::mem::transmute(()) };
23-
| ^^^^^^^^^^^^^^^^^^^
24-
|
25-
= note: source type: `()` (0 bits)
26-
= note: target type: `S` (size can vary because of [u8])
27-
28-
error: aborting due to 2 previous errors
19+
error: aborting due to 1 previous error
2920

30-
Some errors have detailed explanations: E0277, E0512.
31-
For more information about an error, try `rustc --explain E0277`.
21+
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)