@@ -8,18 +8,17 @@ use itertools::Itertools;
8
8
use rspirv:: spirv:: { Dim , ImageFormat , StorageClass , Word } ;
9
9
use rustc_abi:: ExternAbi as Abi ;
10
10
use rustc_abi:: {
11
- Align , BackendRepr , FieldIdx , FieldsShape , HasDataLayout as _ , LayoutData , Primitive ,
12
- ReprFlags , ReprOptions , Scalar , Size , TagEncoding , VariantIdx , Variants ,
11
+ Align , BackendRepr , FieldIdx , FieldsShape , LayoutData , Primitive , ReprFlags , ReprOptions ,
12
+ Scalar , Size , TagEncoding , VariantIdx , Variants ,
13
13
} ;
14
14
use rustc_data_structures:: fx:: FxHashMap ;
15
15
use rustc_errors:: ErrorGuaranteed ;
16
- use rustc_hashes:: Hash64 ;
17
- use rustc_index:: Idx ;
16
+ use rustc_index:: { Idx , IndexVec } ;
18
17
use rustc_middle:: query:: Providers ;
19
18
use rustc_middle:: ty:: layout:: { FnAbiOf , LayoutOf , TyAndLayout } ;
20
19
use rustc_middle:: ty:: {
21
- self , Const , CoroutineArgs , CoroutineArgsExt as _, FloatTy , IntTy , PolyFnSig , Ty , TyCtxt ,
22
- TyKind , UintTy ,
20
+ self , Const , CoroutineArgs , CoroutineArgsExt as _, FieldDef , FloatTy , IntTy , PolyFnSig , Ty ,
21
+ TyCtxt , TyKind , UintTy , VariantDef ,
23
22
} ;
24
23
use rustc_middle:: ty:: { GenericArgsRef , ScalarInt } ;
25
24
use rustc_middle:: { bug, span_bug} ;
@@ -164,9 +163,12 @@ pub(crate) fn provide(providers: &mut Providers) {
164
163
}
165
164
}
166
165
167
- providers. layout_of = |tcx : TyCtxt < ' _ > ,
168
- key : ty:: PseudoCanonicalInput < ' _ , Ty < ' _ > > |
169
- -> Result < TyAndLayout < ' _ > , & ' _ ty:: layout:: LayoutError < ' _ > > {
166
+ providers. layout_of = layout_of;
167
+
168
+ fn layout_of < ' tcx > (
169
+ tcx : TyCtxt < ' tcx > ,
170
+ mut key : ty:: PseudoCanonicalInput < ' tcx , Ty < ' tcx > > ,
171
+ ) -> Result < TyAndLayout < ' tcx > , & ' tcx ty:: layout:: LayoutError < ' tcx > > {
170
172
// HACK(eddyb) to special-case any types at all, they must be normalized,
171
173
// but when normalization would be needed, `layout_of`'s default provider
172
174
// recurses (supposedly for caching reasons), i.e. its calls `layout_of`
@@ -176,76 +178,51 @@ pub(crate) fn provide(providers: &mut Providers) {
176
178
177
179
// HACK(eddyb) bypassing upstream `#[repr(simd)]` changes (see also
178
180
// the later comment above `check_well_formed`, for more details).
179
- let reimplement_old_style_repr_simd = match ty. kind ( ) {
181
+ match ty. kind ( ) {
180
182
ty:: Adt ( def, args) if def. repr ( ) . simd ( ) && !def. repr ( ) . packed ( ) && def. is_struct ( ) => {
181
- Some ( def. non_enum_variant ( ) ) . and_then ( |v| {
182
- let ( count, e_ty) = v
183
- . fields
183
+ let def: & ty:: AdtDef < ' tcx > = def;
184
+ let args: & ty:: GenericArgs < ' tcx > = args;
185
+
186
+ let mut repr_flags = def. repr ( ) . flags ;
187
+ repr_flags. remove ( ReprFlags :: IS_SIMD ) ;
188
+ repr_flags. insert ( ReprFlags :: IS_C ) ;
189
+ let def_c = tcx. mk_adt_def (
190
+ def. did ( ) ,
191
+ def. adt_kind ( ) ,
192
+ def. variants ( )
184
193
. iter ( )
185
- . map ( |f| f. ty ( tcx, args) )
186
- . dedup_with_count ( )
187
- . exactly_one ( )
188
- . ok ( ) ?;
189
- let e_len = u64:: try_from ( count) . ok ( ) . filter ( |& e_len| e_len > 1 ) ?;
190
- Some ( ( def, e_ty, e_len) )
191
- } )
194
+ . map ( |v| {
195
+ VariantDef :: new (
196
+ v. name ,
197
+ None ,
198
+ v. ctor ,
199
+ v. discr ,
200
+ v. fields
201
+ . iter ( )
202
+ . map ( |f| FieldDef {
203
+ did : f. did ,
204
+ name : f. name ,
205
+ vis : f. vis ,
206
+ safety : f. safety ,
207
+ value : f. value ,
208
+ } )
209
+ . collect ( ) ,
210
+ v. def_id ,
211
+ None ,
212
+ v. is_field_list_non_exhaustive ( ) ,
213
+ )
214
+ } )
215
+ . collect ( ) ,
216
+ ReprOptions {
217
+ flags : repr_flags,
218
+ ..def. repr ( )
219
+ } ,
220
+ ) ;
221
+ key. value = Ty :: new_adt ( tcx, def_c, args) ;
192
222
}
193
- _ => None ,
223
+ _ => ( ) ,
194
224
} ;
195
225
196
- // HACK(eddyb) tweaked copy of the old upstream logic for `#[repr(simd)]`:
197
- // https://github.com/rust-lang/rust/blob/1.86.0/compiler/rustc_ty_utils/src/layout.rs#L464-L590
198
- if let Some ( ( adt_def, e_ty, e_len) ) = reimplement_old_style_repr_simd {
199
- let cx = rustc_middle:: ty:: layout:: LayoutCx :: new (
200
- tcx,
201
- key. typing_env . with_post_analysis_normalized ( tcx) ,
202
- ) ;
203
- let dl = cx. data_layout ( ) ;
204
-
205
- // Compute the ABI of the element type:
206
- let e_ly = cx. layout_of ( e_ty) ?;
207
- let BackendRepr :: Scalar ( e_repr) = e_ly. backend_repr else {
208
- // This error isn't caught in typeck, e.g., if
209
- // the element type of the vector is generic.
210
- tcx. dcx ( ) . span_fatal (
211
- tcx. def_span ( adt_def. did ( ) ) ,
212
- format ! (
213
- "SIMD type `{ty}` with a non-primitive-scalar \
214
- (integer/float/pointer) element type `{}`",
215
- e_ly. ty
216
- ) ,
217
- ) ;
218
- } ;
219
-
220
- // Compute the size and alignment of the vector:
221
- let size = e_ly. size . checked_mul ( e_len, dl) . unwrap ( ) ;
222
- let align = dl. llvmlike_vector_align ( size) ;
223
- let size = size. align_to ( align. abi ) ;
224
-
225
- let layout = tcx. mk_layout ( LayoutData {
226
- variants : Variants :: Single {
227
- index : rustc_abi:: FIRST_VARIANT ,
228
- } ,
229
- fields : FieldsShape :: Array {
230
- stride : e_ly. size ,
231
- count : e_len,
232
- } ,
233
- backend_repr : BackendRepr :: SimdVector {
234
- element : e_repr,
235
- count : e_len,
236
- } ,
237
- largest_niche : e_ly. largest_niche ,
238
- uninhabited : false ,
239
- size,
240
- align,
241
- max_repr_align : None ,
242
- unadjusted_abi_align : align. abi ,
243
- randomization_seed : e_ly. randomization_seed . wrapping_add ( Hash64 :: new ( e_len) ) ,
244
- } ) ;
245
-
246
- return Ok ( TyAndLayout { ty, layout } ) ;
247
- }
248
-
249
226
let TyAndLayout { ty, mut layout } =
250
227
( rustc_interface:: DEFAULT_QUERY_PROVIDERS . layout_of ) ( tcx, key) ?;
251
228
@@ -270,7 +247,7 @@ pub(crate) fn provide(providers: &mut Providers) {
270
247
}
271
248
272
249
Ok ( TyAndLayout { ty, layout } )
273
- } ;
250
+ }
274
251
275
252
// HACK(eddyb) work around https://github.com/rust-lang/rust/pull/129403
276
253
// banning "struct-style" `#[repr(simd)]` (in favor of "array-newtype-style"),
0 commit comments