@@ -6,19 +6,19 @@ use crate::codegen_cx::CodegenCx;
6
6
use crate :: spirv_type:: SpirvType ;
7
7
use itertools:: Itertools ;
8
8
use rspirv:: spirv:: { Dim , ImageFormat , StorageClass , Word } ;
9
- use rustc_abi:: ExternAbi as Abi ;
10
9
use rustc_abi:: {
11
10
Align , BackendRepr , FieldIdx , FieldsShape , LayoutData , Primitive , ReprFlags , ReprOptions ,
12
11
Scalar , Size , TagEncoding , VariantIdx , Variants ,
13
12
} ;
13
+ use rustc_abi:: { ExternAbi as Abi , Integer } ;
14
14
use rustc_data_structures:: fx:: FxHashMap ;
15
15
use rustc_errors:: ErrorGuaranteed ;
16
16
use rustc_index:: { Idx , IndexVec } ;
17
17
use rustc_middle:: query:: Providers ;
18
- use rustc_middle:: ty:: layout:: { FnAbiOf , LayoutOf , TyAndLayout } ;
18
+ use rustc_middle:: ty:: layout:: { FnAbiOf , HasTyCtxt , LayoutCx , LayoutOf , TyAndLayout } ;
19
19
use rustc_middle:: ty:: {
20
- self , Const , CoroutineArgs , CoroutineArgsExt as _, FieldDef , FloatTy , IntTy , PolyFnSig , Ty ,
21
- TyCtxt , TyKind , UintTy , VariantDef ,
20
+ self , Const , CoroutineArgs , CoroutineArgsExt as _, FloatTy , IntTy , PolyFnSig , Ty , TyCtxt ,
21
+ TyKind , UintTy ,
22
22
} ;
23
23
use rustc_middle:: ty:: { GenericArgsRef , ScalarInt } ;
24
24
use rustc_middle:: { bug, span_bug} ;
@@ -167,14 +167,17 @@ pub(crate) fn provide(providers: &mut Providers) {
167
167
168
168
fn layout_of < ' tcx > (
169
169
tcx : TyCtxt < ' tcx > ,
170
- mut key : ty:: PseudoCanonicalInput < ' tcx , Ty < ' tcx > > ,
170
+ key : ty:: PseudoCanonicalInput < ' tcx , Ty < ' tcx > > ,
171
171
) -> Result < TyAndLayout < ' tcx > , & ' tcx ty:: layout:: LayoutError < ' tcx > > {
172
172
// HACK(eddyb) to special-case any types at all, they must be normalized,
173
173
// but when normalization would be needed, `layout_of`'s default provider
174
174
// recurses (supposedly for caching reasons), i.e. its calls `layout_of`
175
175
// w/ the normalized type in input, which once again reaches this hook,
176
176
// without ever needing any explicit normalization here.
177
- let ty = key. value ;
177
+ let ty:: PseudoCanonicalInput {
178
+ typing_env,
179
+ value : ty,
180
+ } = key;
178
181
179
182
// HACK(eddyb) bypassing upstream `#[repr(simd)]` changes (see also
180
183
// the later comment above `check_well_formed`, for more details).
@@ -183,42 +186,56 @@ pub(crate) fn provide(providers: &mut Providers) {
183
186
let def: & ty:: AdtDef < ' tcx > = def;
184
187
let args: & ty:: GenericArgs < ' tcx > = args;
185
188
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 ( )
193
- . iter ( )
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
- } ,
189
+ // HACK(firestar99) we don't special case SIMD anymore for glam
190
+ // we now want it to behave like `#[repr(C)]`. But to not break
191
+ // old versions of glam immediately, I made this hack to remap
192
+ // SIMD to C.
193
+ let mut repr = def. repr ( ) ;
194
+ repr. flags . remove ( ReprFlags :: IS_SIMD ) ;
195
+ repr. flags . insert ( ReprFlags :: IS_C ) ;
196
+
197
+ // Much of the following is copied from `rustc_ty_utils::layout::layout_of_uncached` and simplified
198
+ let cx = LayoutCx :: new ( tcx, typing_env) ;
199
+
200
+ // Cache the field layouts, copied
201
+ let variants = def
202
+ . variants ( )
203
+ . iter ( )
204
+ . map ( |v| {
205
+ v. fields
206
+ . iter ( )
207
+ . map ( |field| cx. layout_of ( field. ty ( tcx, args) ) )
208
+ . collect :: < Result < IndexVec < _ , _ > , _ > > ( )
209
+ } )
210
+ . collect :: < Result < IndexVec < VariantIdx , _ > , _ > > ( ) ?;
211
+
212
+ let result = cx. calc . layout_of_struct_or_enum (
213
+ & repr,
214
+ & variants,
215
+ // no enum
216
+ false ,
217
+ // does not contain UnsafeCell and variants
218
+ false ,
219
+ // copied
220
+ tcx. layout_scalar_valid_range ( def. did ( ) ) ,
221
+ // ignored, enum only
222
+ |_, _| ( Integer :: I32 , false ) ,
223
+ // ignored, enum only
224
+ std:: iter:: empty ( ) ,
225
+ // ignored, enum only
226
+ false ,
227
+ // we are always sized
228
+ true ,
220
229
) ;
221
- key. value = Ty :: new_adt ( tcx, def_c, args) ;
230
+
231
+ let layout = match result {
232
+ Ok ( layout_data) => tcx. mk_layout ( layout_data) ,
233
+ Err ( e) => cx
234
+ . tcx ( )
235
+ . dcx ( )
236
+ . fatal ( format ! ( "SIMD to C repr remap failed: {e:?}" ) ) ,
237
+ } ;
238
+ return Ok ( TyAndLayout { ty, layout } ) ;
222
239
}
223
240
_ => ( ) ,
224
241
} ;
0 commit comments