Skip to content

Commit 897ddd4

Browse files
authored
Unrolled build for rust-lang#131843
Rollup merge of rust-lang#131843 - workingjubilee:thaw-impossible-reprs, r=lukas-code compiler: Error on layout of enums with invalid reprs Surprising no one, the ICEs with the same message have the same root cause. Invalid reprs can reach layout computation for various reasons. For instance, the compiler may want to use its layout computations to discern if a combination of layout-affecting attributes results in a valid type to begin with by e.g. computing its size. When the input is bad, return an error reflecting that the answer to the question is not a useful one.
2 parents bfab34a + 9f4c915 commit 897ddd4

File tree

8 files changed

+125
-8
lines changed

8 files changed

+125
-8
lines changed

Diff for: compiler/rustc_abi/src/layout.rs

+9
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ pub enum LayoutCalculatorError<F> {
5454

5555
/// A union had no fields.
5656
EmptyUnion,
57+
58+
/// The fields or variants have irreconcilable reprs
59+
ReprConflict,
5760
}
5861

5962
impl<F> LayoutCalculatorError<F> {
@@ -64,6 +67,7 @@ impl<F> LayoutCalculatorError<F> {
6467
}
6568
LayoutCalculatorError::SizeOverflow => LayoutCalculatorError::SizeOverflow,
6669
LayoutCalculatorError::EmptyUnion => LayoutCalculatorError::EmptyUnion,
70+
LayoutCalculatorError::ReprConflict => LayoutCalculatorError::ReprConflict,
6771
}
6872
}
6973

@@ -77,6 +81,7 @@ impl<F> LayoutCalculatorError<F> {
7781
}
7882
LayoutCalculatorError::SizeOverflow => "size overflow",
7983
LayoutCalculatorError::EmptyUnion => "type is a union with no fields",
84+
LayoutCalculatorError::ReprConflict => "type has an invalid repr",
8085
})
8186
}
8287
}
@@ -514,6 +519,10 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
514519
}
515520

516521
let dl = self.cx.data_layout();
522+
// bail if the enum has an incoherent repr that cannot be computed
523+
if repr.packed() {
524+
return Err(LayoutCalculatorError::ReprConflict);
525+
}
517526

518527
let calculate_niche_filling_layout = || -> Option<TmpLayout<FieldIdx, VariantIdx>> {
519528
if dont_niche_optimize_enum {

Diff for: compiler/rustc_ty_utils/src/layout.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ use {rustc_abi as abi, rustc_hir as hir};
3030
use crate::errors::{
3131
MultipleArrayFieldsSimdType, NonPrimitiveSimdType, OversizedSimdType, ZeroLengthSimdType,
3232
};
33-
use crate::layout_sanity_check::sanity_check_layout;
33+
34+
mod invariant;
3435

3536
pub(crate) fn provide(providers: &mut Providers) {
3637
*providers = Providers { layout_of, ..*providers };
@@ -79,7 +80,7 @@ fn layout_of<'tcx>(
7980
record_layout_for_printing(&cx, layout);
8081
}
8182

82-
sanity_check_layout(&cx, &layout);
83+
invariant::partially_check_layout(&cx, &layout);
8384

8485
Ok(layout)
8586
}
@@ -115,6 +116,11 @@ fn map_error<'tcx>(
115116
cx.tcx().dcx().delayed_bug(format!("computed layout of empty union: {ty:?}"));
116117
LayoutError::Unknown(ty)
117118
}
119+
LayoutCalculatorError::ReprConflict => {
120+
// packed enums are the only known trigger of this, but others might arise
121+
cx.tcx().dcx().delayed_bug(format!("computed impossible repr (packed enum?): {ty:?}"));
122+
LayoutError::Unknown(ty)
123+
}
118124
};
119125
error(cx, err)
120126
}

Diff for: compiler/rustc_ty_utils/src/layout_sanity_check.rs renamed to compiler/rustc_ty_utils/src/layout/invariant.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use rustc_middle::ty::layout::{HasTyCtxt, LayoutCx, TyAndLayout};
55
use rustc_target::abi::*;
66

77
/// Enforce some basic invariants on layouts.
8-
pub(super) fn sanity_check_layout<'tcx>(cx: &LayoutCx<'tcx>, layout: &TyAndLayout<'tcx>) {
8+
pub(super) fn partially_check_layout<'tcx>(cx: &LayoutCx<'tcx>, layout: &TyAndLayout<'tcx>) {
99
let tcx = cx.tcx();
1010

1111
// Type-level uninhabitedness should always imply ABI uninhabitedness.

Diff for: compiler/rustc_ty_utils/src/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ mod errors;
2929
mod implied_bounds;
3030
mod instance;
3131
mod layout;
32-
mod layout_sanity_check;
3332
mod needs_drop;
3433
mod opaque_types;
3534
mod representability;

Diff for: tests/crashes/126966.rs renamed to tests/ui/layout/thaw-transmute-invalid-enum.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
1-
//@ known-bug: rust-lang/rust#126966
1+
#![crate_type = "lib"]
2+
23
mod assert {
34
use std::mem::{Assume, TransmuteFrom};
5+
//~^ ERROR: use of unstable library feature 'transmutability'
6+
//~| ERROR: use of unstable library feature 'transmutability'
47

58
pub fn is_transmutable<Src, Dst>()
69
where
710
Dst: TransmuteFrom<Src>,
11+
//~^ ERROR: use of unstable library feature 'transmutability'
812
{
913
}
1014
}
@@ -15,15 +19,18 @@ enum Ox00 {
1519
}
1620

1721
#[repr(C, packed(2))]
22+
//~^ ERROR: attribute should be applied to a struct
1823
enum OxFF {
1924
V = 0xFF,
2025
}
2126

2227
fn test() {
2328
union Superset {
2429
a: Ox00,
30+
//~^ ERROR: field must implement `Copy`
2531
b: OxFF,
2632
}
2733

2834
assert::is_transmutable::<Superset, Subset>();
35+
//~^ ERROR: cannot find type `Subset`
2936
}

Diff for: tests/ui/layout/thaw-transmute-invalid-enum.stderr

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
error[E0412]: cannot find type `Subset` in this scope
2+
--> $DIR/thaw-transmute-invalid-enum.rs:34:41
3+
|
4+
LL | assert::is_transmutable::<Superset, Subset>();
5+
| ^^^^^^ not found in this scope
6+
|
7+
help: you might be missing a type parameter
8+
|
9+
LL | fn test<Subset>() {
10+
| ++++++++
11+
12+
error[E0517]: attribute should be applied to a struct or union
13+
--> $DIR/thaw-transmute-invalid-enum.rs:21:11
14+
|
15+
LL | #[repr(C, packed(2))]
16+
| ^^^^^^^^^
17+
LL |
18+
LL | / enum OxFF {
19+
LL | | V = 0xFF,
20+
LL | | }
21+
| |_- not a struct or union
22+
23+
error[E0658]: use of unstable library feature 'transmutability'
24+
--> $DIR/thaw-transmute-invalid-enum.rs:4:20
25+
|
26+
LL | use std::mem::{Assume, TransmuteFrom};
27+
| ^^^^^^
28+
|
29+
= note: see issue #99571 <https://github.com/rust-lang/rust/issues/99571> for more information
30+
= help: add `#![feature(transmutability)]` to the crate attributes to enable
31+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
32+
33+
error[E0658]: use of unstable library feature 'transmutability'
34+
--> $DIR/thaw-transmute-invalid-enum.rs:4:28
35+
|
36+
LL | use std::mem::{Assume, TransmuteFrom};
37+
| ^^^^^^^^^^^^^
38+
|
39+
= note: see issue #99571 <https://github.com/rust-lang/rust/issues/99571> for more information
40+
= help: add `#![feature(transmutability)]` to the crate attributes to enable
41+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
42+
43+
error[E0658]: use of unstable library feature 'transmutability'
44+
--> $DIR/thaw-transmute-invalid-enum.rs:10:14
45+
|
46+
LL | Dst: TransmuteFrom<Src>,
47+
| ^^^^^^^^^^^^^^^^^^
48+
|
49+
= note: see issue #99571 <https://github.com/rust-lang/rust/issues/99571> for more information
50+
= help: add `#![feature(transmutability)]` to the crate attributes to enable
51+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
52+
53+
error[E0740]: field must implement `Copy` or be wrapped in `ManuallyDrop<...>` to be used in a union
54+
--> $DIR/thaw-transmute-invalid-enum.rs:29:9
55+
|
56+
LL | a: Ox00,
57+
| ^^^^^^^
58+
|
59+
= note: union fields must not have drop side-effects, which is currently enforced via either `Copy` or `ManuallyDrop<...>`
60+
help: wrap the field type in `ManuallyDrop<...>`
61+
|
62+
LL | a: std::mem::ManuallyDrop<Ox00>,
63+
| +++++++++++++++++++++++ +
64+
65+
error: aborting due to 6 previous errors
66+
67+
Some errors have detailed explanations: E0412, E0517, E0658, E0740.
68+
For more information about an error, try `rustc --explain E0412`.
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
//@ known-bug: rust-lang/rust#128870
21
//@ compile-flags: -Zvalidate-mir
32

4-
#[repr(packed)]
3+
#[repr(packed)] //~ ERROR: attribute should be applied to a struct
54
#[repr(u32)]
65
enum E {
76
A,
@@ -12,7 +11,7 @@ enum E {
1211
fn main() {
1312
union InvalidTag {
1413
int: u32,
15-
e: E,
14+
e: E, //~ ERROR: field must implement `Copy`
1615
}
1716
let _invalid_tag = InvalidTag { int: 4 };
1817
}

Diff for: tests/ui/layout/thaw-validate-invalid-enum.stderr

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
error[E0517]: attribute should be applied to a struct or union
2+
--> $DIR/thaw-validate-invalid-enum.rs:3:8
3+
|
4+
LL | #[repr(packed)]
5+
| ^^^^^^
6+
LL | #[repr(u32)]
7+
LL | / enum E {
8+
LL | | A,
9+
LL | | B,
10+
LL | | C,
11+
LL | | }
12+
| |_- not a struct or union
13+
14+
error[E0740]: field must implement `Copy` or be wrapped in `ManuallyDrop<...>` to be used in a union
15+
--> $DIR/thaw-validate-invalid-enum.rs:14:9
16+
|
17+
LL | e: E,
18+
| ^^^^
19+
|
20+
= note: union fields must not have drop side-effects, which is currently enforced via either `Copy` or `ManuallyDrop<...>`
21+
help: wrap the field type in `ManuallyDrop<...>`
22+
|
23+
LL | e: std::mem::ManuallyDrop<E>,
24+
| +++++++++++++++++++++++ +
25+
26+
error: aborting due to 2 previous errors
27+
28+
Some errors have detailed explanations: E0517, E0740.
29+
For more information about an error, try `rustc --explain E0517`.

0 commit comments

Comments
 (0)