File tree 4 files changed +203
-4
lines changed
compiler/rustc_middle/src/ty
4 files changed +203
-4
lines changed Original file line number Diff line number Diff line change @@ -1418,9 +1418,9 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
1418
1418
1419
1419
if layout_variants. iter ( ) . all ( |v| v. abi . is_uninhabited ( ) ) {
1420
1420
abi = Abi :: Uninhabited ;
1421
- } else if tag. size ( dl) == size || variants . iter ( ) . all ( |layout| layout . is_empty ( ) ) {
1422
- // Without latter check aligned enums with custom discriminant values
1423
- // Would result in ICE see the issue #92464 for more info
1421
+ } else if tag. size ( dl) == size {
1422
+ // Make sure we only use scalar layout when the enum is entirely its
1423
+ // own tag (i.e. it has no padding nor any non-ZST variant fields).
1424
1424
abi = Abi :: Scalar ( tag) ;
1425
1425
} else {
1426
1426
// Try to use a ScalarPair for all tagged enums.
Original file line number Diff line number Diff line change @@ -11,5 +11,13 @@ enum Aligned {
11
11
fn main ( ) {
12
12
let aligned = Aligned :: Zero ;
13
13
let fo = aligned as u8 ;
14
- println ! ( "foo {}" , fo) ;
14
+ println ! ( "foo {}" , fo) ;
15
+ println ! ( "{}" , tou8( Aligned :: Zero ) ) ;
16
+ }
17
+
18
+ #[ inline( never) ]
19
+ fn tou8 ( al : Aligned ) -> u8 {
20
+ // Cast behind a function call so ConstProp does not see it
21
+ // (so that we can test codegen).
22
+ al as u8
15
23
}
Original file line number Diff line number Diff line change
1
+ // normalize-stderr-test "pref: Align\([1-8] bytes\)" -> "pref: $$PREF_ALIGN"
2
+ #![ crate_type = "lib" ]
3
+ #![ feature( rustc_attrs) ]
4
+
5
+ // This cannot use `Scalar` abi since there is padding.
6
+ #[ rustc_layout( debug) ]
7
+ #[ repr( align( 8 ) ) ]
8
+ pub enum Aligned1 { //~ ERROR: layout_of
9
+ Zero = 0 ,
10
+ One = 1 ,
11
+ }
12
+
13
+ // This should use `Scalar` abi.
14
+ #[ rustc_layout( debug) ]
15
+ #[ repr( align( 1 ) ) ]
16
+ pub enum Aligned2 { //~ ERROR: layout_of
17
+ Zero = 0 ,
18
+ One = 1 ,
19
+ }
Original file line number Diff line number Diff line change
1
+ error: layout_of(Aligned1) = Layout {
2
+ fields: Arbitrary {
3
+ offsets: [
4
+ Size(0 bytes),
5
+ ],
6
+ memory_index: [
7
+ 0,
8
+ ],
9
+ },
10
+ variants: Multiple {
11
+ tag: Initialized {
12
+ value: Int(
13
+ I8,
14
+ false,
15
+ ),
16
+ valid_range: 0..=1,
17
+ },
18
+ tag_encoding: Direct,
19
+ tag_field: 0,
20
+ variants: [
21
+ Layout {
22
+ fields: Arbitrary {
23
+ offsets: [],
24
+ memory_index: [],
25
+ },
26
+ variants: Single {
27
+ index: 0,
28
+ },
29
+ abi: Aggregate {
30
+ sized: true,
31
+ },
32
+ largest_niche: None,
33
+ align: AbiAndPrefAlign {
34
+ abi: Align(8 bytes),
35
+ pref: $PREF_ALIGN,
36
+ },
37
+ size: Size(8 bytes),
38
+ },
39
+ Layout {
40
+ fields: Arbitrary {
41
+ offsets: [],
42
+ memory_index: [],
43
+ },
44
+ variants: Single {
45
+ index: 1,
46
+ },
47
+ abi: Aggregate {
48
+ sized: true,
49
+ },
50
+ largest_niche: None,
51
+ align: AbiAndPrefAlign {
52
+ abi: Align(8 bytes),
53
+ pref: $PREF_ALIGN,
54
+ },
55
+ size: Size(8 bytes),
56
+ },
57
+ ],
58
+ },
59
+ abi: Aggregate {
60
+ sized: true,
61
+ },
62
+ largest_niche: Some(
63
+ Niche {
64
+ offset: Size(0 bytes),
65
+ value: Int(
66
+ I8,
67
+ false,
68
+ ),
69
+ valid_range: 0..=1,
70
+ },
71
+ ),
72
+ align: AbiAndPrefAlign {
73
+ abi: Align(8 bytes),
74
+ pref: $PREF_ALIGN,
75
+ },
76
+ size: Size(8 bytes),
77
+ }
78
+ --> $DIR/issue-96185-overaligned-enum.rs:8:1
79
+ |
80
+ LL | pub enum Aligned1 {
81
+ | ^^^^^^^^^^^^^^^^^
82
+
83
+ error: layout_of(Aligned2) = Layout {
84
+ fields: Arbitrary {
85
+ offsets: [
86
+ Size(0 bytes),
87
+ ],
88
+ memory_index: [
89
+ 0,
90
+ ],
91
+ },
92
+ variants: Multiple {
93
+ tag: Initialized {
94
+ value: Int(
95
+ I8,
96
+ false,
97
+ ),
98
+ valid_range: 0..=1,
99
+ },
100
+ tag_encoding: Direct,
101
+ tag_field: 0,
102
+ variants: [
103
+ Layout {
104
+ fields: Arbitrary {
105
+ offsets: [],
106
+ memory_index: [],
107
+ },
108
+ variants: Single {
109
+ index: 0,
110
+ },
111
+ abi: Aggregate {
112
+ sized: true,
113
+ },
114
+ largest_niche: None,
115
+ align: AbiAndPrefAlign {
116
+ abi: Align(1 bytes),
117
+ pref: $PREF_ALIGN,
118
+ },
119
+ size: Size(1 bytes),
120
+ },
121
+ Layout {
122
+ fields: Arbitrary {
123
+ offsets: [],
124
+ memory_index: [],
125
+ },
126
+ variants: Single {
127
+ index: 1,
128
+ },
129
+ abi: Aggregate {
130
+ sized: true,
131
+ },
132
+ largest_niche: None,
133
+ align: AbiAndPrefAlign {
134
+ abi: Align(1 bytes),
135
+ pref: $PREF_ALIGN,
136
+ },
137
+ size: Size(1 bytes),
138
+ },
139
+ ],
140
+ },
141
+ abi: Scalar(
142
+ Initialized {
143
+ value: Int(
144
+ I8,
145
+ false,
146
+ ),
147
+ valid_range: 0..=1,
148
+ },
149
+ ),
150
+ largest_niche: Some(
151
+ Niche {
152
+ offset: Size(0 bytes),
153
+ value: Int(
154
+ I8,
155
+ false,
156
+ ),
157
+ valid_range: 0..=1,
158
+ },
159
+ ),
160
+ align: AbiAndPrefAlign {
161
+ abi: Align(1 bytes),
162
+ pref: $PREF_ALIGN,
163
+ },
164
+ size: Size(1 bytes),
165
+ }
166
+ --> $DIR/issue-96185-overaligned-enum.rs:16:1
167
+ |
168
+ LL | pub enum Aligned2 {
169
+ | ^^^^^^^^^^^^^^^^^
170
+
171
+ error: aborting due to 2 previous errors
172
+
You can’t perform that action at this time.
0 commit comments