mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-26 00:34:06 +00:00
Rollup merge of #123043 - GoldsteinE:fix/repr-c-dead-branches, r=oli-obk
Disable dead variant removal for `#[repr(C)]` enums. This prevents removing dead branches from a `#[repr(C)]` enum (they now get discriminants allocated as if they were inhabited). Implementation notes: ABI of something like ```rust #[repr(C)] enum Foo { Foo(!), } ``` is still `Uninhabited`, but its layout is now computed as if all the branches were inhabited. This seemed to me like a proper way to do it, especially given that ABI sanity check explicitly asserts that type-level uninhabitedness implies ABI uninhabitedness. This probably needs some sort of FCP (given that it changes `#[repr(C)]` layout, which is a stable guarantee), but I’m not sure how to call for one or which team is the most relevant. See https://github.com/rust-lang/unsafe-code-guidelines/issues/500.
This commit is contained in:
commit
f0a0f8f7e8
@ -186,7 +186,7 @@ pub trait LayoutCalculator {
|
|||||||
let (present_first, present_second) = {
|
let (present_first, present_second) = {
|
||||||
let mut present_variants = variants
|
let mut present_variants = variants
|
||||||
.iter_enumerated()
|
.iter_enumerated()
|
||||||
.filter_map(|(i, v)| if absent(v) { None } else { Some(i) });
|
.filter_map(|(i, v)| if !repr.c() && absent(v) { None } else { Some(i) });
|
||||||
(present_variants.next(), present_variants.next())
|
(present_variants.next(), present_variants.next())
|
||||||
};
|
};
|
||||||
let present_first = match present_first {
|
let present_first = match present_first {
|
||||||
@ -621,7 +621,7 @@ where
|
|||||||
let discr_type = repr.discr_type();
|
let discr_type = repr.discr_type();
|
||||||
let bits = Integer::from_attr(dl, discr_type).size().bits();
|
let bits = Integer::from_attr(dl, discr_type).size().bits();
|
||||||
for (i, mut val) in discriminants {
|
for (i, mut val) in discriminants {
|
||||||
if variants[i].iter().any(|f| f.abi.is_uninhabited()) {
|
if !repr.c() && variants[i].iter().any(|f| f.abi.is_uninhabited()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if discr_type.is_signed() {
|
if discr_type.is_signed() {
|
||||||
|
@ -1429,7 +1429,7 @@ pub enum Variants<FieldIdx: Idx, VariantIdx: Idx> {
|
|||||||
/// Single enum variants, structs/tuples, unions, and all non-ADTs.
|
/// Single enum variants, structs/tuples, unions, and all non-ADTs.
|
||||||
Single { index: VariantIdx },
|
Single { index: VariantIdx },
|
||||||
|
|
||||||
/// Enum-likes with more than one inhabited variant: each variant comes with
|
/// Enum-likes with more than one variant: each variant comes with
|
||||||
/// a *discriminant* (usually the same as the variant index but the user can
|
/// a *discriminant* (usually the same as the variant index but the user can
|
||||||
/// assign explicit discriminant values). That discriminant is encoded
|
/// assign explicit discriminant values). That discriminant is encoded
|
||||||
/// as a *tag* on the machine. The layout of each variant is
|
/// as a *tag* on the machine. The layout of each variant is
|
||||||
|
@ -271,6 +271,11 @@ test_abi_compatible!(zst_unit, Zst, ());
|
|||||||
test_abi_compatible!(zst_array, Zst, [u8; 0]);
|
test_abi_compatible!(zst_array, Zst, [u8; 0]);
|
||||||
test_abi_compatible!(nonzero_int, NonZero<i32>, i32);
|
test_abi_compatible!(nonzero_int, NonZero<i32>, i32);
|
||||||
|
|
||||||
|
// `#[repr(C)]` enums should not change ABI based on individual variant inhabitedness.
|
||||||
|
// (However, this is *not* a guarantee. We only guarantee same layout, not same ABI.)
|
||||||
|
enum Void {}
|
||||||
|
test_abi_compatible!(repr_c_enum_void, ReprCEnum<Void>, ReprCEnum<ReprCUnion<Void>>);
|
||||||
|
|
||||||
// `DispatchFromDyn` relies on ABI compatibility.
|
// `DispatchFromDyn` relies on ABI compatibility.
|
||||||
// This is interesting since these types are not `repr(transparent)`. So this is not part of our
|
// This is interesting since these types are not `repr(transparent)`. So this is not part of our
|
||||||
// public ABI guarantees, but is relied on by the compiler.
|
// public ABI guarantees, but is relied on by the compiler.
|
||||||
|
@ -0,0 +1,288 @@
|
|||||||
|
error: layout_of(Univariant) = Layout {
|
||||||
|
size: Size(4 bytes),
|
||||||
|
align: AbiAndPrefAlign {
|
||||||
|
abi: Align(4 bytes),
|
||||||
|
pref: $SOME_ALIGN,
|
||||||
|
},
|
||||||
|
abi: Uninhabited,
|
||||||
|
fields: Arbitrary {
|
||||||
|
offsets: [
|
||||||
|
Size(0 bytes),
|
||||||
|
],
|
||||||
|
memory_index: [
|
||||||
|
0,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
largest_niche: Some(
|
||||||
|
Niche {
|
||||||
|
offset: Size(0 bytes),
|
||||||
|
value: Int(
|
||||||
|
I32,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
valid_range: 0..=0,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
variants: Multiple {
|
||||||
|
tag: Initialized {
|
||||||
|
value: Int(
|
||||||
|
I32,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
valid_range: 0..=0,
|
||||||
|
},
|
||||||
|
tag_encoding: Direct,
|
||||||
|
tag_field: 0,
|
||||||
|
variants: [
|
||||||
|
Layout {
|
||||||
|
size: Size(4 bytes),
|
||||||
|
align: AbiAndPrefAlign {
|
||||||
|
abi: Align(4 bytes),
|
||||||
|
pref: $SOME_ALIGN,
|
||||||
|
},
|
||||||
|
abi: Uninhabited,
|
||||||
|
fields: Arbitrary {
|
||||||
|
offsets: [
|
||||||
|
Size(4 bytes),
|
||||||
|
],
|
||||||
|
memory_index: [
|
||||||
|
0,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
largest_niche: None,
|
||||||
|
variants: Single {
|
||||||
|
index: 0,
|
||||||
|
},
|
||||||
|
max_repr_align: None,
|
||||||
|
unadjusted_abi_align: Align(4 bytes),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
max_repr_align: None,
|
||||||
|
unadjusted_abi_align: Align(4 bytes),
|
||||||
|
}
|
||||||
|
--> $DIR/repr-c-dead-variants.rs:38:1
|
||||||
|
|
|
||||||
|
LL | enum Univariant {
|
||||||
|
| ^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: layout_of(TwoVariants) = Layout {
|
||||||
|
size: Size(8 bytes),
|
||||||
|
align: AbiAndPrefAlign {
|
||||||
|
abi: Align(4 bytes),
|
||||||
|
pref: $SOME_ALIGN,
|
||||||
|
},
|
||||||
|
abi: ScalarPair(
|
||||||
|
Initialized {
|
||||||
|
value: Int(
|
||||||
|
I32,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
valid_range: 0..=1,
|
||||||
|
},
|
||||||
|
Union {
|
||||||
|
value: Int(
|
||||||
|
I8,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
fields: Arbitrary {
|
||||||
|
offsets: [
|
||||||
|
Size(0 bytes),
|
||||||
|
],
|
||||||
|
memory_index: [
|
||||||
|
0,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
largest_niche: Some(
|
||||||
|
Niche {
|
||||||
|
offset: Size(0 bytes),
|
||||||
|
value: Int(
|
||||||
|
I32,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
valid_range: 0..=1,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
variants: Multiple {
|
||||||
|
tag: Initialized {
|
||||||
|
value: Int(
|
||||||
|
I32,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
valid_range: 0..=1,
|
||||||
|
},
|
||||||
|
tag_encoding: Direct,
|
||||||
|
tag_field: 0,
|
||||||
|
variants: [
|
||||||
|
Layout {
|
||||||
|
size: Size(4 bytes),
|
||||||
|
align: AbiAndPrefAlign {
|
||||||
|
abi: Align(4 bytes),
|
||||||
|
pref: $SOME_ALIGN,
|
||||||
|
},
|
||||||
|
abi: Uninhabited,
|
||||||
|
fields: Arbitrary {
|
||||||
|
offsets: [
|
||||||
|
Size(4 bytes),
|
||||||
|
],
|
||||||
|
memory_index: [
|
||||||
|
0,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
largest_niche: None,
|
||||||
|
variants: Single {
|
||||||
|
index: 0,
|
||||||
|
},
|
||||||
|
max_repr_align: None,
|
||||||
|
unadjusted_abi_align: Align(4 bytes),
|
||||||
|
},
|
||||||
|
Layout {
|
||||||
|
size: Size(8 bytes),
|
||||||
|
align: AbiAndPrefAlign {
|
||||||
|
abi: Align(4 bytes),
|
||||||
|
pref: $SOME_ALIGN,
|
||||||
|
},
|
||||||
|
abi: ScalarPair(
|
||||||
|
Initialized {
|
||||||
|
value: Int(
|
||||||
|
I32,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
valid_range: 0..=1,
|
||||||
|
},
|
||||||
|
Union {
|
||||||
|
value: Int(
|
||||||
|
I8,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
fields: Arbitrary {
|
||||||
|
offsets: [
|
||||||
|
Size(4 bytes),
|
||||||
|
],
|
||||||
|
memory_index: [
|
||||||
|
0,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
largest_niche: None,
|
||||||
|
variants: Single {
|
||||||
|
index: 1,
|
||||||
|
},
|
||||||
|
max_repr_align: None,
|
||||||
|
unadjusted_abi_align: Align(4 bytes),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
max_repr_align: None,
|
||||||
|
unadjusted_abi_align: Align(4 bytes),
|
||||||
|
}
|
||||||
|
--> $DIR/repr-c-dead-variants.rs:45:1
|
||||||
|
|
|
||||||
|
LL | enum TwoVariants {
|
||||||
|
| ^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: layout_of(DeadBranchHasOtherField) = Layout {
|
||||||
|
size: Size(16 bytes),
|
||||||
|
align: AbiAndPrefAlign {
|
||||||
|
abi: Align(8 bytes),
|
||||||
|
pref: $SOME_ALIGN,
|
||||||
|
},
|
||||||
|
abi: Aggregate {
|
||||||
|
sized: true,
|
||||||
|
},
|
||||||
|
fields: Arbitrary {
|
||||||
|
offsets: [
|
||||||
|
Size(0 bytes),
|
||||||
|
],
|
||||||
|
memory_index: [
|
||||||
|
0,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
largest_niche: Some(
|
||||||
|
Niche {
|
||||||
|
offset: Size(0 bytes),
|
||||||
|
value: Int(
|
||||||
|
I32,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
valid_range: 0..=1,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
variants: Multiple {
|
||||||
|
tag: Initialized {
|
||||||
|
value: Int(
|
||||||
|
I32,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
valid_range: 0..=1,
|
||||||
|
},
|
||||||
|
tag_encoding: Direct,
|
||||||
|
tag_field: 0,
|
||||||
|
variants: [
|
||||||
|
Layout {
|
||||||
|
size: Size(16 bytes),
|
||||||
|
align: AbiAndPrefAlign {
|
||||||
|
abi: Align(8 bytes),
|
||||||
|
pref: $SOME_ALIGN,
|
||||||
|
},
|
||||||
|
abi: Uninhabited,
|
||||||
|
fields: Arbitrary {
|
||||||
|
offsets: [
|
||||||
|
Size(8 bytes),
|
||||||
|
Size(8 bytes),
|
||||||
|
],
|
||||||
|
memory_index: [
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
largest_niche: None,
|
||||||
|
variants: Single {
|
||||||
|
index: 0,
|
||||||
|
},
|
||||||
|
max_repr_align: Some(
|
||||||
|
Align(8 bytes),
|
||||||
|
),
|
||||||
|
unadjusted_abi_align: Align(8 bytes),
|
||||||
|
},
|
||||||
|
Layout {
|
||||||
|
size: Size(16 bytes),
|
||||||
|
align: AbiAndPrefAlign {
|
||||||
|
abi: Align(8 bytes),
|
||||||
|
pref: $SOME_ALIGN,
|
||||||
|
},
|
||||||
|
abi: Aggregate {
|
||||||
|
sized: true,
|
||||||
|
},
|
||||||
|
fields: Arbitrary {
|
||||||
|
offsets: [
|
||||||
|
Size(8 bytes),
|
||||||
|
],
|
||||||
|
memory_index: [
|
||||||
|
0,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
largest_niche: None,
|
||||||
|
variants: Single {
|
||||||
|
index: 1,
|
||||||
|
},
|
||||||
|
max_repr_align: None,
|
||||||
|
unadjusted_abi_align: Align(8 bytes),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
max_repr_align: Some(
|
||||||
|
Align(8 bytes),
|
||||||
|
),
|
||||||
|
unadjusted_abi_align: Align(8 bytes),
|
||||||
|
}
|
||||||
|
--> $DIR/repr-c-dead-variants.rs:57:1
|
||||||
|
|
|
||||||
|
LL | enum DeadBranchHasOtherField {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 3 previous errors
|
||||||
|
|
288
tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr
Normal file
288
tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr
Normal file
@ -0,0 +1,288 @@
|
|||||||
|
error: layout_of(Univariant) = Layout {
|
||||||
|
size: Size(1 bytes),
|
||||||
|
align: AbiAndPrefAlign {
|
||||||
|
abi: Align(1 bytes),
|
||||||
|
pref: $SOME_ALIGN,
|
||||||
|
},
|
||||||
|
abi: Uninhabited,
|
||||||
|
fields: Arbitrary {
|
||||||
|
offsets: [
|
||||||
|
Size(0 bytes),
|
||||||
|
],
|
||||||
|
memory_index: [
|
||||||
|
0,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
largest_niche: Some(
|
||||||
|
Niche {
|
||||||
|
offset: Size(0 bytes),
|
||||||
|
value: Int(
|
||||||
|
I8,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
valid_range: 0..=0,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
variants: Multiple {
|
||||||
|
tag: Initialized {
|
||||||
|
value: Int(
|
||||||
|
I8,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
valid_range: 0..=0,
|
||||||
|
},
|
||||||
|
tag_encoding: Direct,
|
||||||
|
tag_field: 0,
|
||||||
|
variants: [
|
||||||
|
Layout {
|
||||||
|
size: Size(1 bytes),
|
||||||
|
align: AbiAndPrefAlign {
|
||||||
|
abi: Align(1 bytes),
|
||||||
|
pref: $SOME_ALIGN,
|
||||||
|
},
|
||||||
|
abi: Uninhabited,
|
||||||
|
fields: Arbitrary {
|
||||||
|
offsets: [
|
||||||
|
Size(1 bytes),
|
||||||
|
],
|
||||||
|
memory_index: [
|
||||||
|
0,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
largest_niche: None,
|
||||||
|
variants: Single {
|
||||||
|
index: 0,
|
||||||
|
},
|
||||||
|
max_repr_align: None,
|
||||||
|
unadjusted_abi_align: Align(1 bytes),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
max_repr_align: None,
|
||||||
|
unadjusted_abi_align: Align(1 bytes),
|
||||||
|
}
|
||||||
|
--> $DIR/repr-c-dead-variants.rs:38:1
|
||||||
|
|
|
||||||
|
LL | enum Univariant {
|
||||||
|
| ^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: layout_of(TwoVariants) = Layout {
|
||||||
|
size: Size(2 bytes),
|
||||||
|
align: AbiAndPrefAlign {
|
||||||
|
abi: Align(1 bytes),
|
||||||
|
pref: $SOME_ALIGN,
|
||||||
|
},
|
||||||
|
abi: ScalarPair(
|
||||||
|
Initialized {
|
||||||
|
value: Int(
|
||||||
|
I8,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
valid_range: 0..=1,
|
||||||
|
},
|
||||||
|
Union {
|
||||||
|
value: Int(
|
||||||
|
I8,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
fields: Arbitrary {
|
||||||
|
offsets: [
|
||||||
|
Size(0 bytes),
|
||||||
|
],
|
||||||
|
memory_index: [
|
||||||
|
0,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
largest_niche: Some(
|
||||||
|
Niche {
|
||||||
|
offset: Size(0 bytes),
|
||||||
|
value: Int(
|
||||||
|
I8,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
valid_range: 0..=1,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
variants: Multiple {
|
||||||
|
tag: Initialized {
|
||||||
|
value: Int(
|
||||||
|
I8,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
valid_range: 0..=1,
|
||||||
|
},
|
||||||
|
tag_encoding: Direct,
|
||||||
|
tag_field: 0,
|
||||||
|
variants: [
|
||||||
|
Layout {
|
||||||
|
size: Size(1 bytes),
|
||||||
|
align: AbiAndPrefAlign {
|
||||||
|
abi: Align(1 bytes),
|
||||||
|
pref: $SOME_ALIGN,
|
||||||
|
},
|
||||||
|
abi: Uninhabited,
|
||||||
|
fields: Arbitrary {
|
||||||
|
offsets: [
|
||||||
|
Size(1 bytes),
|
||||||
|
],
|
||||||
|
memory_index: [
|
||||||
|
0,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
largest_niche: None,
|
||||||
|
variants: Single {
|
||||||
|
index: 0,
|
||||||
|
},
|
||||||
|
max_repr_align: None,
|
||||||
|
unadjusted_abi_align: Align(1 bytes),
|
||||||
|
},
|
||||||
|
Layout {
|
||||||
|
size: Size(2 bytes),
|
||||||
|
align: AbiAndPrefAlign {
|
||||||
|
abi: Align(1 bytes),
|
||||||
|
pref: $SOME_ALIGN,
|
||||||
|
},
|
||||||
|
abi: ScalarPair(
|
||||||
|
Initialized {
|
||||||
|
value: Int(
|
||||||
|
I8,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
valid_range: 0..=1,
|
||||||
|
},
|
||||||
|
Union {
|
||||||
|
value: Int(
|
||||||
|
I8,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
fields: Arbitrary {
|
||||||
|
offsets: [
|
||||||
|
Size(1 bytes),
|
||||||
|
],
|
||||||
|
memory_index: [
|
||||||
|
0,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
largest_niche: None,
|
||||||
|
variants: Single {
|
||||||
|
index: 1,
|
||||||
|
},
|
||||||
|
max_repr_align: None,
|
||||||
|
unadjusted_abi_align: Align(1 bytes),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
max_repr_align: None,
|
||||||
|
unadjusted_abi_align: Align(1 bytes),
|
||||||
|
}
|
||||||
|
--> $DIR/repr-c-dead-variants.rs:45:1
|
||||||
|
|
|
||||||
|
LL | enum TwoVariants {
|
||||||
|
| ^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: layout_of(DeadBranchHasOtherField) = Layout {
|
||||||
|
size: Size(16 bytes),
|
||||||
|
align: AbiAndPrefAlign {
|
||||||
|
abi: Align(8 bytes),
|
||||||
|
pref: $SOME_ALIGN,
|
||||||
|
},
|
||||||
|
abi: Aggregate {
|
||||||
|
sized: true,
|
||||||
|
},
|
||||||
|
fields: Arbitrary {
|
||||||
|
offsets: [
|
||||||
|
Size(0 bytes),
|
||||||
|
],
|
||||||
|
memory_index: [
|
||||||
|
0,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
largest_niche: Some(
|
||||||
|
Niche {
|
||||||
|
offset: Size(0 bytes),
|
||||||
|
value: Int(
|
||||||
|
I8,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
valid_range: 0..=1,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
variants: Multiple {
|
||||||
|
tag: Initialized {
|
||||||
|
value: Int(
|
||||||
|
I8,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
valid_range: 0..=1,
|
||||||
|
},
|
||||||
|
tag_encoding: Direct,
|
||||||
|
tag_field: 0,
|
||||||
|
variants: [
|
||||||
|
Layout {
|
||||||
|
size: Size(16 bytes),
|
||||||
|
align: AbiAndPrefAlign {
|
||||||
|
abi: Align(8 bytes),
|
||||||
|
pref: $SOME_ALIGN,
|
||||||
|
},
|
||||||
|
abi: Uninhabited,
|
||||||
|
fields: Arbitrary {
|
||||||
|
offsets: [
|
||||||
|
Size(8 bytes),
|
||||||
|
Size(8 bytes),
|
||||||
|
],
|
||||||
|
memory_index: [
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
largest_niche: None,
|
||||||
|
variants: Single {
|
||||||
|
index: 0,
|
||||||
|
},
|
||||||
|
max_repr_align: Some(
|
||||||
|
Align(8 bytes),
|
||||||
|
),
|
||||||
|
unadjusted_abi_align: Align(8 bytes),
|
||||||
|
},
|
||||||
|
Layout {
|
||||||
|
size: Size(16 bytes),
|
||||||
|
align: AbiAndPrefAlign {
|
||||||
|
abi: Align(8 bytes),
|
||||||
|
pref: $SOME_ALIGN,
|
||||||
|
},
|
||||||
|
abi: Aggregate {
|
||||||
|
sized: true,
|
||||||
|
},
|
||||||
|
fields: Arbitrary {
|
||||||
|
offsets: [
|
||||||
|
Size(8 bytes),
|
||||||
|
],
|
||||||
|
memory_index: [
|
||||||
|
0,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
largest_niche: None,
|
||||||
|
variants: Single {
|
||||||
|
index: 1,
|
||||||
|
},
|
||||||
|
max_repr_align: None,
|
||||||
|
unadjusted_abi_align: Align(8 bytes),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
max_repr_align: Some(
|
||||||
|
Align(8 bytes),
|
||||||
|
),
|
||||||
|
unadjusted_abi_align: Align(8 bytes),
|
||||||
|
}
|
||||||
|
--> $DIR/repr-c-dead-variants.rs:57:1
|
||||||
|
|
|
||||||
|
LL | enum DeadBranchHasOtherField {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 3 previous errors
|
||||||
|
|
288
tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr
Normal file
288
tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr
Normal file
@ -0,0 +1,288 @@
|
|||||||
|
error: layout_of(Univariant) = Layout {
|
||||||
|
size: Size(4 bytes),
|
||||||
|
align: AbiAndPrefAlign {
|
||||||
|
abi: Align(4 bytes),
|
||||||
|
pref: $SOME_ALIGN,
|
||||||
|
},
|
||||||
|
abi: Uninhabited,
|
||||||
|
fields: Arbitrary {
|
||||||
|
offsets: [
|
||||||
|
Size(0 bytes),
|
||||||
|
],
|
||||||
|
memory_index: [
|
||||||
|
0,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
largest_niche: Some(
|
||||||
|
Niche {
|
||||||
|
offset: Size(0 bytes),
|
||||||
|
value: Int(
|
||||||
|
I32,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
valid_range: 0..=0,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
variants: Multiple {
|
||||||
|
tag: Initialized {
|
||||||
|
value: Int(
|
||||||
|
I32,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
valid_range: 0..=0,
|
||||||
|
},
|
||||||
|
tag_encoding: Direct,
|
||||||
|
tag_field: 0,
|
||||||
|
variants: [
|
||||||
|
Layout {
|
||||||
|
size: Size(4 bytes),
|
||||||
|
align: AbiAndPrefAlign {
|
||||||
|
abi: Align(4 bytes),
|
||||||
|
pref: $SOME_ALIGN,
|
||||||
|
},
|
||||||
|
abi: Uninhabited,
|
||||||
|
fields: Arbitrary {
|
||||||
|
offsets: [
|
||||||
|
Size(4 bytes),
|
||||||
|
],
|
||||||
|
memory_index: [
|
||||||
|
0,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
largest_niche: None,
|
||||||
|
variants: Single {
|
||||||
|
index: 0,
|
||||||
|
},
|
||||||
|
max_repr_align: None,
|
||||||
|
unadjusted_abi_align: Align(4 bytes),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
max_repr_align: None,
|
||||||
|
unadjusted_abi_align: Align(4 bytes),
|
||||||
|
}
|
||||||
|
--> $DIR/repr-c-dead-variants.rs:38:1
|
||||||
|
|
|
||||||
|
LL | enum Univariant {
|
||||||
|
| ^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: layout_of(TwoVariants) = Layout {
|
||||||
|
size: Size(8 bytes),
|
||||||
|
align: AbiAndPrefAlign {
|
||||||
|
abi: Align(4 bytes),
|
||||||
|
pref: $SOME_ALIGN,
|
||||||
|
},
|
||||||
|
abi: ScalarPair(
|
||||||
|
Initialized {
|
||||||
|
value: Int(
|
||||||
|
I32,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
valid_range: 0..=1,
|
||||||
|
},
|
||||||
|
Union {
|
||||||
|
value: Int(
|
||||||
|
I8,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
fields: Arbitrary {
|
||||||
|
offsets: [
|
||||||
|
Size(0 bytes),
|
||||||
|
],
|
||||||
|
memory_index: [
|
||||||
|
0,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
largest_niche: Some(
|
||||||
|
Niche {
|
||||||
|
offset: Size(0 bytes),
|
||||||
|
value: Int(
|
||||||
|
I32,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
valid_range: 0..=1,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
variants: Multiple {
|
||||||
|
tag: Initialized {
|
||||||
|
value: Int(
|
||||||
|
I32,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
valid_range: 0..=1,
|
||||||
|
},
|
||||||
|
tag_encoding: Direct,
|
||||||
|
tag_field: 0,
|
||||||
|
variants: [
|
||||||
|
Layout {
|
||||||
|
size: Size(4 bytes),
|
||||||
|
align: AbiAndPrefAlign {
|
||||||
|
abi: Align(4 bytes),
|
||||||
|
pref: $SOME_ALIGN,
|
||||||
|
},
|
||||||
|
abi: Uninhabited,
|
||||||
|
fields: Arbitrary {
|
||||||
|
offsets: [
|
||||||
|
Size(4 bytes),
|
||||||
|
],
|
||||||
|
memory_index: [
|
||||||
|
0,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
largest_niche: None,
|
||||||
|
variants: Single {
|
||||||
|
index: 0,
|
||||||
|
},
|
||||||
|
max_repr_align: None,
|
||||||
|
unadjusted_abi_align: Align(4 bytes),
|
||||||
|
},
|
||||||
|
Layout {
|
||||||
|
size: Size(8 bytes),
|
||||||
|
align: AbiAndPrefAlign {
|
||||||
|
abi: Align(4 bytes),
|
||||||
|
pref: $SOME_ALIGN,
|
||||||
|
},
|
||||||
|
abi: ScalarPair(
|
||||||
|
Initialized {
|
||||||
|
value: Int(
|
||||||
|
I32,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
valid_range: 0..=1,
|
||||||
|
},
|
||||||
|
Union {
|
||||||
|
value: Int(
|
||||||
|
I8,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
fields: Arbitrary {
|
||||||
|
offsets: [
|
||||||
|
Size(4 bytes),
|
||||||
|
],
|
||||||
|
memory_index: [
|
||||||
|
0,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
largest_niche: None,
|
||||||
|
variants: Single {
|
||||||
|
index: 1,
|
||||||
|
},
|
||||||
|
max_repr_align: None,
|
||||||
|
unadjusted_abi_align: Align(4 bytes),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
max_repr_align: None,
|
||||||
|
unadjusted_abi_align: Align(4 bytes),
|
||||||
|
}
|
||||||
|
--> $DIR/repr-c-dead-variants.rs:45:1
|
||||||
|
|
|
||||||
|
LL | enum TwoVariants {
|
||||||
|
| ^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: layout_of(DeadBranchHasOtherField) = Layout {
|
||||||
|
size: Size(16 bytes),
|
||||||
|
align: AbiAndPrefAlign {
|
||||||
|
abi: Align(8 bytes),
|
||||||
|
pref: $SOME_ALIGN,
|
||||||
|
},
|
||||||
|
abi: Aggregate {
|
||||||
|
sized: true,
|
||||||
|
},
|
||||||
|
fields: Arbitrary {
|
||||||
|
offsets: [
|
||||||
|
Size(0 bytes),
|
||||||
|
],
|
||||||
|
memory_index: [
|
||||||
|
0,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
largest_niche: Some(
|
||||||
|
Niche {
|
||||||
|
offset: Size(0 bytes),
|
||||||
|
value: Int(
|
||||||
|
I32,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
valid_range: 0..=1,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
variants: Multiple {
|
||||||
|
tag: Initialized {
|
||||||
|
value: Int(
|
||||||
|
I32,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
valid_range: 0..=1,
|
||||||
|
},
|
||||||
|
tag_encoding: Direct,
|
||||||
|
tag_field: 0,
|
||||||
|
variants: [
|
||||||
|
Layout {
|
||||||
|
size: Size(16 bytes),
|
||||||
|
align: AbiAndPrefAlign {
|
||||||
|
abi: Align(8 bytes),
|
||||||
|
pref: $SOME_ALIGN,
|
||||||
|
},
|
||||||
|
abi: Uninhabited,
|
||||||
|
fields: Arbitrary {
|
||||||
|
offsets: [
|
||||||
|
Size(8 bytes),
|
||||||
|
Size(8 bytes),
|
||||||
|
],
|
||||||
|
memory_index: [
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
largest_niche: None,
|
||||||
|
variants: Single {
|
||||||
|
index: 0,
|
||||||
|
},
|
||||||
|
max_repr_align: Some(
|
||||||
|
Align(8 bytes),
|
||||||
|
),
|
||||||
|
unadjusted_abi_align: Align(8 bytes),
|
||||||
|
},
|
||||||
|
Layout {
|
||||||
|
size: Size(16 bytes),
|
||||||
|
align: AbiAndPrefAlign {
|
||||||
|
abi: Align(8 bytes),
|
||||||
|
pref: $SOME_ALIGN,
|
||||||
|
},
|
||||||
|
abi: Aggregate {
|
||||||
|
sized: true,
|
||||||
|
},
|
||||||
|
fields: Arbitrary {
|
||||||
|
offsets: [
|
||||||
|
Size(8 bytes),
|
||||||
|
],
|
||||||
|
memory_index: [
|
||||||
|
0,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
largest_niche: None,
|
||||||
|
variants: Single {
|
||||||
|
index: 1,
|
||||||
|
},
|
||||||
|
max_repr_align: None,
|
||||||
|
unadjusted_abi_align: Align(8 bytes),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
max_repr_align: Some(
|
||||||
|
Align(8 bytes),
|
||||||
|
),
|
||||||
|
unadjusted_abi_align: Align(8 bytes),
|
||||||
|
}
|
||||||
|
--> $DIR/repr-c-dead-variants.rs:57:1
|
||||||
|
|
|
||||||
|
LL | enum DeadBranchHasOtherField {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 3 previous errors
|
||||||
|
|
63
tests/ui/repr/repr-c-dead-variants.rs
Normal file
63
tests/ui/repr/repr-c-dead-variants.rs
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
#![feature(no_core, rustc_attrs, lang_items)]
|
||||||
|
#![allow(dead_code)]
|
||||||
|
#![crate_type = "lib"]
|
||||||
|
#![no_std]
|
||||||
|
#![no_core]
|
||||||
|
|
||||||
|
// See also: repr-c-int-dead-variants.rs
|
||||||
|
|
||||||
|
//@ normalize-stderr-test "pref: Align\([1-8] bytes\)" -> "pref: $$SOME_ALIGN"
|
||||||
|
|
||||||
|
// This test depends on the value of the `c_enum_min_bits` target option.
|
||||||
|
// As there's no way to actually check it from UI test, we only run this test on a subset of archs.
|
||||||
|
// Four archs specifically are chosen: one for major architectures (x86_64, i686, aarch64)
|
||||||
|
// and `armebv7r-none-eabi` that has `c_enum_min_bits` set to 8.
|
||||||
|
|
||||||
|
//@ revisions: aarch64-unknown-linux-gnu
|
||||||
|
//@[aarch64-unknown-linux-gnu] compile-flags: --target aarch64-unknown-linux-gnu
|
||||||
|
//@[aarch64-unknown-linux-gnu] needs-llvm-components: aarch64
|
||||||
|
|
||||||
|
//@ revisions: i686-pc-windows-msvc
|
||||||
|
//@[i686-pc-windows-msvc] compile-flags: --target i686-pc-windows-gnu
|
||||||
|
//@[i686-pc-windows-msvc] needs-llvm-components: x86
|
||||||
|
|
||||||
|
//@ revisions: x86_64-unknown-linux-gnu
|
||||||
|
//@[x86_64-unknown-linux-gnu] compile-flags: --target x86_64-unknown-linux-gnu
|
||||||
|
//@[x86_64-unknown-linux-gnu] needs-llvm-components: x86
|
||||||
|
//
|
||||||
|
//@ revisions: armebv7r-none-eabi
|
||||||
|
//@[armebv7r-none-eabi] compile-flags: --target armebv7r-none-eabi
|
||||||
|
//@[armebv7r-none-eabi] needs-llvm-components: arm
|
||||||
|
|
||||||
|
// A simple uninhabited type.
|
||||||
|
enum Void {}
|
||||||
|
|
||||||
|
// Compiler must not remove dead variants of `#[repr(C, int)]` ADTs.
|
||||||
|
#[repr(C)]
|
||||||
|
#[rustc_layout(debug)]
|
||||||
|
enum Univariant { //~ ERROR layout_of
|
||||||
|
Variant(Void),
|
||||||
|
}
|
||||||
|
|
||||||
|
// ADTs with variants that have fields must have space allocated for those fields.
|
||||||
|
#[repr(C)]
|
||||||
|
#[rustc_layout(debug)]
|
||||||
|
enum TwoVariants { //~ ERROR layout_of
|
||||||
|
Variant1(Void),
|
||||||
|
Variant2(u8),
|
||||||
|
}
|
||||||
|
|
||||||
|
// Some targets have 4-byte-aligned u64, make it always 8-byte-aligned.
|
||||||
|
#[repr(C, align(8))]
|
||||||
|
struct Align8U64(u64);
|
||||||
|
|
||||||
|
// This one is 2 x u64: we reserve space for fields in a dead branch.
|
||||||
|
#[repr(C)]
|
||||||
|
#[rustc_layout(debug)]
|
||||||
|
enum DeadBranchHasOtherField { //~ ERROR layout_of
|
||||||
|
Variant1(Void, Align8U64),
|
||||||
|
Variant2(u8),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[lang = "sized"]
|
||||||
|
trait Sized {}
|
@ -0,0 +1,288 @@
|
|||||||
|
error: layout_of(Univariant) = Layout {
|
||||||
|
size: Size(4 bytes),
|
||||||
|
align: AbiAndPrefAlign {
|
||||||
|
abi: Align(4 bytes),
|
||||||
|
pref: $SOME_ALIGN,
|
||||||
|
},
|
||||||
|
abi: Uninhabited,
|
||||||
|
fields: Arbitrary {
|
||||||
|
offsets: [
|
||||||
|
Size(0 bytes),
|
||||||
|
],
|
||||||
|
memory_index: [
|
||||||
|
0,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
largest_niche: Some(
|
||||||
|
Niche {
|
||||||
|
offset: Size(0 bytes),
|
||||||
|
value: Int(
|
||||||
|
I32,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
valid_range: 0..=0,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
variants: Multiple {
|
||||||
|
tag: Initialized {
|
||||||
|
value: Int(
|
||||||
|
I32,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
valid_range: 0..=0,
|
||||||
|
},
|
||||||
|
tag_encoding: Direct,
|
||||||
|
tag_field: 0,
|
||||||
|
variants: [
|
||||||
|
Layout {
|
||||||
|
size: Size(4 bytes),
|
||||||
|
align: AbiAndPrefAlign {
|
||||||
|
abi: Align(4 bytes),
|
||||||
|
pref: $SOME_ALIGN,
|
||||||
|
},
|
||||||
|
abi: Uninhabited,
|
||||||
|
fields: Arbitrary {
|
||||||
|
offsets: [
|
||||||
|
Size(4 bytes),
|
||||||
|
],
|
||||||
|
memory_index: [
|
||||||
|
0,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
largest_niche: None,
|
||||||
|
variants: Single {
|
||||||
|
index: 0,
|
||||||
|
},
|
||||||
|
max_repr_align: None,
|
||||||
|
unadjusted_abi_align: Align(4 bytes),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
max_repr_align: None,
|
||||||
|
unadjusted_abi_align: Align(4 bytes),
|
||||||
|
}
|
||||||
|
--> $DIR/repr-c-dead-variants.rs:38:1
|
||||||
|
|
|
||||||
|
LL | enum Univariant {
|
||||||
|
| ^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: layout_of(TwoVariants) = Layout {
|
||||||
|
size: Size(8 bytes),
|
||||||
|
align: AbiAndPrefAlign {
|
||||||
|
abi: Align(4 bytes),
|
||||||
|
pref: $SOME_ALIGN,
|
||||||
|
},
|
||||||
|
abi: ScalarPair(
|
||||||
|
Initialized {
|
||||||
|
value: Int(
|
||||||
|
I32,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
valid_range: 0..=1,
|
||||||
|
},
|
||||||
|
Union {
|
||||||
|
value: Int(
|
||||||
|
I8,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
fields: Arbitrary {
|
||||||
|
offsets: [
|
||||||
|
Size(0 bytes),
|
||||||
|
],
|
||||||
|
memory_index: [
|
||||||
|
0,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
largest_niche: Some(
|
||||||
|
Niche {
|
||||||
|
offset: Size(0 bytes),
|
||||||
|
value: Int(
|
||||||
|
I32,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
valid_range: 0..=1,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
variants: Multiple {
|
||||||
|
tag: Initialized {
|
||||||
|
value: Int(
|
||||||
|
I32,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
valid_range: 0..=1,
|
||||||
|
},
|
||||||
|
tag_encoding: Direct,
|
||||||
|
tag_field: 0,
|
||||||
|
variants: [
|
||||||
|
Layout {
|
||||||
|
size: Size(4 bytes),
|
||||||
|
align: AbiAndPrefAlign {
|
||||||
|
abi: Align(4 bytes),
|
||||||
|
pref: $SOME_ALIGN,
|
||||||
|
},
|
||||||
|
abi: Uninhabited,
|
||||||
|
fields: Arbitrary {
|
||||||
|
offsets: [
|
||||||
|
Size(4 bytes),
|
||||||
|
],
|
||||||
|
memory_index: [
|
||||||
|
0,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
largest_niche: None,
|
||||||
|
variants: Single {
|
||||||
|
index: 0,
|
||||||
|
},
|
||||||
|
max_repr_align: None,
|
||||||
|
unadjusted_abi_align: Align(4 bytes),
|
||||||
|
},
|
||||||
|
Layout {
|
||||||
|
size: Size(8 bytes),
|
||||||
|
align: AbiAndPrefAlign {
|
||||||
|
abi: Align(4 bytes),
|
||||||
|
pref: $SOME_ALIGN,
|
||||||
|
},
|
||||||
|
abi: ScalarPair(
|
||||||
|
Initialized {
|
||||||
|
value: Int(
|
||||||
|
I32,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
valid_range: 0..=1,
|
||||||
|
},
|
||||||
|
Union {
|
||||||
|
value: Int(
|
||||||
|
I8,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
fields: Arbitrary {
|
||||||
|
offsets: [
|
||||||
|
Size(4 bytes),
|
||||||
|
],
|
||||||
|
memory_index: [
|
||||||
|
0,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
largest_niche: None,
|
||||||
|
variants: Single {
|
||||||
|
index: 1,
|
||||||
|
},
|
||||||
|
max_repr_align: None,
|
||||||
|
unadjusted_abi_align: Align(4 bytes),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
max_repr_align: None,
|
||||||
|
unadjusted_abi_align: Align(4 bytes),
|
||||||
|
}
|
||||||
|
--> $DIR/repr-c-dead-variants.rs:45:1
|
||||||
|
|
|
||||||
|
LL | enum TwoVariants {
|
||||||
|
| ^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: layout_of(DeadBranchHasOtherField) = Layout {
|
||||||
|
size: Size(16 bytes),
|
||||||
|
align: AbiAndPrefAlign {
|
||||||
|
abi: Align(8 bytes),
|
||||||
|
pref: $SOME_ALIGN,
|
||||||
|
},
|
||||||
|
abi: Aggregate {
|
||||||
|
sized: true,
|
||||||
|
},
|
||||||
|
fields: Arbitrary {
|
||||||
|
offsets: [
|
||||||
|
Size(0 bytes),
|
||||||
|
],
|
||||||
|
memory_index: [
|
||||||
|
0,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
largest_niche: Some(
|
||||||
|
Niche {
|
||||||
|
offset: Size(0 bytes),
|
||||||
|
value: Int(
|
||||||
|
I32,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
valid_range: 0..=1,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
variants: Multiple {
|
||||||
|
tag: Initialized {
|
||||||
|
value: Int(
|
||||||
|
I32,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
valid_range: 0..=1,
|
||||||
|
},
|
||||||
|
tag_encoding: Direct,
|
||||||
|
tag_field: 0,
|
||||||
|
variants: [
|
||||||
|
Layout {
|
||||||
|
size: Size(16 bytes),
|
||||||
|
align: AbiAndPrefAlign {
|
||||||
|
abi: Align(8 bytes),
|
||||||
|
pref: $SOME_ALIGN,
|
||||||
|
},
|
||||||
|
abi: Uninhabited,
|
||||||
|
fields: Arbitrary {
|
||||||
|
offsets: [
|
||||||
|
Size(8 bytes),
|
||||||
|
Size(8 bytes),
|
||||||
|
],
|
||||||
|
memory_index: [
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
largest_niche: None,
|
||||||
|
variants: Single {
|
||||||
|
index: 0,
|
||||||
|
},
|
||||||
|
max_repr_align: Some(
|
||||||
|
Align(8 bytes),
|
||||||
|
),
|
||||||
|
unadjusted_abi_align: Align(8 bytes),
|
||||||
|
},
|
||||||
|
Layout {
|
||||||
|
size: Size(16 bytes),
|
||||||
|
align: AbiAndPrefAlign {
|
||||||
|
abi: Align(8 bytes),
|
||||||
|
pref: $SOME_ALIGN,
|
||||||
|
},
|
||||||
|
abi: Aggregate {
|
||||||
|
sized: true,
|
||||||
|
},
|
||||||
|
fields: Arbitrary {
|
||||||
|
offsets: [
|
||||||
|
Size(8 bytes),
|
||||||
|
],
|
||||||
|
memory_index: [
|
||||||
|
0,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
largest_niche: None,
|
||||||
|
variants: Single {
|
||||||
|
index: 1,
|
||||||
|
},
|
||||||
|
max_repr_align: None,
|
||||||
|
unadjusted_abi_align: Align(8 bytes),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
max_repr_align: Some(
|
||||||
|
Align(8 bytes),
|
||||||
|
),
|
||||||
|
unadjusted_abi_align: Align(8 bytes),
|
||||||
|
}
|
||||||
|
--> $DIR/repr-c-dead-variants.rs:57:1
|
||||||
|
|
|
||||||
|
LL | enum DeadBranchHasOtherField {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 3 previous errors
|
||||||
|
|
38
tests/ui/repr/repr-c-int-dead-variants.rs
Normal file
38
tests/ui/repr/repr-c-int-dead-variants.rs
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
#![feature(rustc_attrs)]
|
||||||
|
#![allow(dead_code)]
|
||||||
|
|
||||||
|
// See also: repr-c-dead-variants.rs
|
||||||
|
|
||||||
|
//@ normalize-stderr-test "pref: Align\([1-8] bytes\)" -> "pref: $$SOME_ALIGN"
|
||||||
|
|
||||||
|
// A simple uninhabited type.
|
||||||
|
enum Void {}
|
||||||
|
|
||||||
|
// Compiler must not remove dead variants of `#[repr(C, int)]` ADTs.
|
||||||
|
#[repr(C, u8)]
|
||||||
|
#[rustc_layout(debug)]
|
||||||
|
enum UnivariantU8 { //~ ERROR layout_of
|
||||||
|
Variant(Void),
|
||||||
|
}
|
||||||
|
|
||||||
|
// ADTs with variants that have fields must have space allocated for those fields.
|
||||||
|
#[repr(C, u8)]
|
||||||
|
#[rustc_layout(debug)]
|
||||||
|
enum TwoVariantsU8 { //~ ERROR layout_of
|
||||||
|
Variant1(Void),
|
||||||
|
Variant2(u8),
|
||||||
|
}
|
||||||
|
|
||||||
|
// Some targets have 4-byte-aligned u64, make it always 8-byte-aligned.
|
||||||
|
#[repr(C, align(8))]
|
||||||
|
struct Align8U64(u64);
|
||||||
|
|
||||||
|
// This one is 2 x u64: we reserve space for fields in a dead branch.
|
||||||
|
#[repr(C, u8)]
|
||||||
|
#[rustc_layout(debug)]
|
||||||
|
enum DeadBranchHasOtherFieldU8 { //~ ERROR layout_of
|
||||||
|
Variant1(Void, Align8U64),
|
||||||
|
Variant2(u8),
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
288
tests/ui/repr/repr-c-int-dead-variants.stderr
Normal file
288
tests/ui/repr/repr-c-int-dead-variants.stderr
Normal file
@ -0,0 +1,288 @@
|
|||||||
|
error: layout_of(UnivariantU8) = Layout {
|
||||||
|
size: Size(1 bytes),
|
||||||
|
align: AbiAndPrefAlign {
|
||||||
|
abi: Align(1 bytes),
|
||||||
|
pref: $SOME_ALIGN,
|
||||||
|
},
|
||||||
|
abi: Uninhabited,
|
||||||
|
fields: Arbitrary {
|
||||||
|
offsets: [
|
||||||
|
Size(0 bytes),
|
||||||
|
],
|
||||||
|
memory_index: [
|
||||||
|
0,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
largest_niche: Some(
|
||||||
|
Niche {
|
||||||
|
offset: Size(0 bytes),
|
||||||
|
value: Int(
|
||||||
|
I8,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
valid_range: 0..=0,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
variants: Multiple {
|
||||||
|
tag: Initialized {
|
||||||
|
value: Int(
|
||||||
|
I8,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
valid_range: 0..=0,
|
||||||
|
},
|
||||||
|
tag_encoding: Direct,
|
||||||
|
tag_field: 0,
|
||||||
|
variants: [
|
||||||
|
Layout {
|
||||||
|
size: Size(1 bytes),
|
||||||
|
align: AbiAndPrefAlign {
|
||||||
|
abi: Align(1 bytes),
|
||||||
|
pref: $SOME_ALIGN,
|
||||||
|
},
|
||||||
|
abi: Uninhabited,
|
||||||
|
fields: Arbitrary {
|
||||||
|
offsets: [
|
||||||
|
Size(1 bytes),
|
||||||
|
],
|
||||||
|
memory_index: [
|
||||||
|
0,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
largest_niche: None,
|
||||||
|
variants: Single {
|
||||||
|
index: 0,
|
||||||
|
},
|
||||||
|
max_repr_align: None,
|
||||||
|
unadjusted_abi_align: Align(1 bytes),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
max_repr_align: None,
|
||||||
|
unadjusted_abi_align: Align(1 bytes),
|
||||||
|
}
|
||||||
|
--> $DIR/repr-c-int-dead-variants.rs:14:1
|
||||||
|
|
|
||||||
|
LL | enum UnivariantU8 {
|
||||||
|
| ^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: layout_of(TwoVariantsU8) = Layout {
|
||||||
|
size: Size(2 bytes),
|
||||||
|
align: AbiAndPrefAlign {
|
||||||
|
abi: Align(1 bytes),
|
||||||
|
pref: $SOME_ALIGN,
|
||||||
|
},
|
||||||
|
abi: ScalarPair(
|
||||||
|
Initialized {
|
||||||
|
value: Int(
|
||||||
|
I8,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
valid_range: 0..=1,
|
||||||
|
},
|
||||||
|
Union {
|
||||||
|
value: Int(
|
||||||
|
I8,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
fields: Arbitrary {
|
||||||
|
offsets: [
|
||||||
|
Size(0 bytes),
|
||||||
|
],
|
||||||
|
memory_index: [
|
||||||
|
0,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
largest_niche: Some(
|
||||||
|
Niche {
|
||||||
|
offset: Size(0 bytes),
|
||||||
|
value: Int(
|
||||||
|
I8,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
valid_range: 0..=1,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
variants: Multiple {
|
||||||
|
tag: Initialized {
|
||||||
|
value: Int(
|
||||||
|
I8,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
valid_range: 0..=1,
|
||||||
|
},
|
||||||
|
tag_encoding: Direct,
|
||||||
|
tag_field: 0,
|
||||||
|
variants: [
|
||||||
|
Layout {
|
||||||
|
size: Size(1 bytes),
|
||||||
|
align: AbiAndPrefAlign {
|
||||||
|
abi: Align(1 bytes),
|
||||||
|
pref: $SOME_ALIGN,
|
||||||
|
},
|
||||||
|
abi: Uninhabited,
|
||||||
|
fields: Arbitrary {
|
||||||
|
offsets: [
|
||||||
|
Size(1 bytes),
|
||||||
|
],
|
||||||
|
memory_index: [
|
||||||
|
0,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
largest_niche: None,
|
||||||
|
variants: Single {
|
||||||
|
index: 0,
|
||||||
|
},
|
||||||
|
max_repr_align: None,
|
||||||
|
unadjusted_abi_align: Align(1 bytes),
|
||||||
|
},
|
||||||
|
Layout {
|
||||||
|
size: Size(2 bytes),
|
||||||
|
align: AbiAndPrefAlign {
|
||||||
|
abi: Align(1 bytes),
|
||||||
|
pref: $SOME_ALIGN,
|
||||||
|
},
|
||||||
|
abi: ScalarPair(
|
||||||
|
Initialized {
|
||||||
|
value: Int(
|
||||||
|
I8,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
valid_range: 0..=1,
|
||||||
|
},
|
||||||
|
Union {
|
||||||
|
value: Int(
|
||||||
|
I8,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
fields: Arbitrary {
|
||||||
|
offsets: [
|
||||||
|
Size(1 bytes),
|
||||||
|
],
|
||||||
|
memory_index: [
|
||||||
|
0,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
largest_niche: None,
|
||||||
|
variants: Single {
|
||||||
|
index: 1,
|
||||||
|
},
|
||||||
|
max_repr_align: None,
|
||||||
|
unadjusted_abi_align: Align(1 bytes),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
max_repr_align: None,
|
||||||
|
unadjusted_abi_align: Align(1 bytes),
|
||||||
|
}
|
||||||
|
--> $DIR/repr-c-int-dead-variants.rs:21:1
|
||||||
|
|
|
||||||
|
LL | enum TwoVariantsU8 {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: layout_of(DeadBranchHasOtherFieldU8) = Layout {
|
||||||
|
size: Size(16 bytes),
|
||||||
|
align: AbiAndPrefAlign {
|
||||||
|
abi: Align(8 bytes),
|
||||||
|
pref: $SOME_ALIGN,
|
||||||
|
},
|
||||||
|
abi: Aggregate {
|
||||||
|
sized: true,
|
||||||
|
},
|
||||||
|
fields: Arbitrary {
|
||||||
|
offsets: [
|
||||||
|
Size(0 bytes),
|
||||||
|
],
|
||||||
|
memory_index: [
|
||||||
|
0,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
largest_niche: Some(
|
||||||
|
Niche {
|
||||||
|
offset: Size(0 bytes),
|
||||||
|
value: Int(
|
||||||
|
I8,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
valid_range: 0..=1,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
variants: Multiple {
|
||||||
|
tag: Initialized {
|
||||||
|
value: Int(
|
||||||
|
I8,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
valid_range: 0..=1,
|
||||||
|
},
|
||||||
|
tag_encoding: Direct,
|
||||||
|
tag_field: 0,
|
||||||
|
variants: [
|
||||||
|
Layout {
|
||||||
|
size: Size(16 bytes),
|
||||||
|
align: AbiAndPrefAlign {
|
||||||
|
abi: Align(8 bytes),
|
||||||
|
pref: $SOME_ALIGN,
|
||||||
|
},
|
||||||
|
abi: Uninhabited,
|
||||||
|
fields: Arbitrary {
|
||||||
|
offsets: [
|
||||||
|
Size(8 bytes),
|
||||||
|
Size(8 bytes),
|
||||||
|
],
|
||||||
|
memory_index: [
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
largest_niche: None,
|
||||||
|
variants: Single {
|
||||||
|
index: 0,
|
||||||
|
},
|
||||||
|
max_repr_align: Some(
|
||||||
|
Align(8 bytes),
|
||||||
|
),
|
||||||
|
unadjusted_abi_align: Align(8 bytes),
|
||||||
|
},
|
||||||
|
Layout {
|
||||||
|
size: Size(16 bytes),
|
||||||
|
align: AbiAndPrefAlign {
|
||||||
|
abi: Align(8 bytes),
|
||||||
|
pref: $SOME_ALIGN,
|
||||||
|
},
|
||||||
|
abi: Aggregate {
|
||||||
|
sized: true,
|
||||||
|
},
|
||||||
|
fields: Arbitrary {
|
||||||
|
offsets: [
|
||||||
|
Size(8 bytes),
|
||||||
|
],
|
||||||
|
memory_index: [
|
||||||
|
0,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
largest_niche: None,
|
||||||
|
variants: Single {
|
||||||
|
index: 1,
|
||||||
|
},
|
||||||
|
max_repr_align: None,
|
||||||
|
unadjusted_abi_align: Align(8 bytes),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
max_repr_align: Some(
|
||||||
|
Align(8 bytes),
|
||||||
|
),
|
||||||
|
unadjusted_abi_align: Align(8 bytes),
|
||||||
|
}
|
||||||
|
--> $DIR/repr-c-int-dead-variants.rs:33:1
|
||||||
|
|
|
||||||
|
LL | enum DeadBranchHasOtherFieldU8 {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 3 previous errors
|
||||||
|
|
Loading…
Reference in New Issue
Block a user