@@ -6,24 +6,22 @@ use base_db::ra_salsa::Cycle;
6
6
use chalk_ir:: { AdtId , FloatTy , IntTy , TyKind , UintTy } ;
7
7
use hir_def:: {
8
8
layout:: {
9
- BackendRepr , FieldsShape , Float , Integer , LayoutCalculator , LayoutCalculatorError ,
10
- LayoutData , Primitive , ReprOptions , Scalar , Size , StructKind , TargetDataLayout ,
9
+ Float , Integer , LayoutCalculator , LayoutCalculatorError ,
10
+ LayoutData , Primitive , ReprOptions , Scalar , StructKind , TargetDataLayout ,
11
11
WrappingRange ,
12
12
} ,
13
13
LocalFieldId , StructId ,
14
14
} ;
15
15
use la_arena:: { Idx , RawIdx } ;
16
16
use rustc_abi:: AddressSpace ;
17
- use rustc_hashes:: Hash64 ;
18
- use rustc_index:: { IndexSlice , IndexVec } ;
17
+ use rustc_index:: IndexVec ;
19
18
20
19
use triomphe:: Arc ;
21
20
22
21
use crate :: {
23
22
consteval:: try_const_usize,
24
23
db:: { HirDatabase , InternedClosure } ,
25
24
infer:: normalize,
26
- layout:: adt:: struct_variant_idx,
27
25
utils:: ClosureSubst ,
28
26
Interner , ProjectionTy , Substitution , TraitEnvironment , Ty ,
29
27
} ;
@@ -125,82 +123,34 @@ impl<'a> LayoutCx<'a> {
125
123
}
126
124
}
127
125
128
- // FIXME: move this to the `rustc_abi`.
129
126
fn layout_of_simd_ty (
130
127
db : & dyn HirDatabase ,
131
128
id : StructId ,
129
+ repr_packed : bool ,
132
130
subst : & Substitution ,
133
131
env : Arc < TraitEnvironment > ,
134
132
dl : & TargetDataLayout ,
135
133
) -> Result < Arc < Layout > , LayoutError > {
136
- let fields = db. field_types ( id. into ( ) ) ;
137
-
138
- // Supported SIMD vectors are homogeneous ADTs with at least one field:
134
+ // Supported SIMD vectors are homogeneous ADTs with exactly one array field:
139
135
//
140
- // * #[repr(simd)] struct S(T, T, T, T);
141
- // * #[repr(simd)] struct S { it: T, y: T, z: T, w: T }
142
136
// * #[repr(simd)] struct S([T; 4])
143
137
//
144
138
// where T is a primitive scalar (integer/float/pointer).
145
-
146
- let f0_ty = match fields. iter ( ) . next ( ) {
147
- Some ( it) => it. 1 . clone ( ) . substitute ( Interner , subst) ,
148
- None => return Err ( LayoutError :: InvalidSimdType ) ,
149
- } ;
150
-
151
- // The element type and number of elements of the SIMD vector
152
- // are obtained from:
153
- //
154
- // * the element type and length of the single array field, if
155
- // the first field is of array type, or
156
- //
157
- // * the homogeneous field type and the number of fields.
158
- let ( e_ty, e_len, is_array) = if let TyKind :: Array ( e_ty, _) = f0_ty. kind ( Interner ) {
159
- // Extract the number of elements from the layout of the array field:
160
- let FieldsShape :: Array { count, .. } = db. layout_of_ty ( f0_ty. clone ( ) , env. clone ( ) ) ?. fields
161
- else {
162
- return Err ( LayoutError :: Unknown ) ;
163
- } ;
164
-
165
- ( e_ty. clone ( ) , count, true )
166
- } else {
167
- // First ADT field is not an array:
168
- ( f0_ty, fields. iter ( ) . count ( ) as u64 , false )
139
+ let fields = db. field_types ( id. into ( ) ) ;
140
+ let mut fields = fields. iter ( ) ;
141
+ let Some ( TyKind :: Array ( e_ty, e_len) ) = fields
142
+ . next ( )
143
+ . filter ( |_| fields. next ( ) . is_none ( ) )
144
+ . map ( |f| f. 1 . clone ( ) . substitute ( Interner , subst) . kind ( Interner ) . clone ( ) )
145
+ else {
146
+ return Err ( LayoutError :: InvalidSimdType ) ;
169
147
} ;
170
148
171
- // Compute the ABI of the element type:
149
+ let e_len = try_const_usize ( db , & e_len ) . ok_or ( LayoutError :: HasErrorConst ) ? as u64 ;
172
150
let e_ly = db. layout_of_ty ( e_ty, env) ?;
173
- let BackendRepr :: Scalar ( e_abi) = e_ly. backend_repr else {
174
- return Err ( LayoutError :: Unknown ) ;
175
- } ;
176
151
177
- // Compute the size and alignment of the vector:
178
- let size = e_ly
179
- . size
180
- . checked_mul ( e_len, dl)
181
- . ok_or ( LayoutError :: BadCalc ( LayoutCalculatorError :: SizeOverflow ) ) ?;
182
- let align = dl. llvmlike_vector_align ( size) ;
183
- let size = size. align_to ( align. abi ) ;
184
-
185
- // Compute the placement of the vector fields:
186
- let fields = if is_array {
187
- FieldsShape :: Arbitrary { offsets : [ Size :: ZERO ] . into ( ) , memory_index : [ 0 ] . into ( ) }
188
- } else {
189
- FieldsShape :: Array { stride : e_ly. size , count : e_len }
190
- } ;
191
-
192
- Ok ( Arc :: new ( Layout {
193
- variants : Variants :: Single { index : struct_variant_idx ( ) } ,
194
- fields,
195
- backend_repr : BackendRepr :: SimdVector { element : e_abi, count : e_len } ,
196
- largest_niche : e_ly. largest_niche ,
197
- uninhabited : false ,
198
- size,
199
- align,
200
- max_repr_align : None ,
201
- unadjusted_abi_align : align. abi ,
202
- randomization_seed : Hash64 :: ZERO ,
203
- } ) )
152
+ let cx = LayoutCx :: new ( dl) ;
153
+ Ok ( Arc :: new ( cx. calc . simd_type ( e_ly, e_len, repr_packed) ?) )
204
154
}
205
155
206
156
pub fn layout_of_ty_query (
@@ -215,13 +165,14 @@ pub fn layout_of_ty_query(
215
165
let dl = & * target;
216
166
let cx = LayoutCx :: new ( dl) ;
217
167
let ty = normalize ( db, trait_env. clone ( ) , ty) ;
218
- let result = match ty. kind ( Interner ) {
168
+ let kind = ty. kind ( Interner ) ;
169
+ let result = match kind {
219
170
TyKind :: Adt ( AdtId ( def) , subst) => {
220
171
if let hir_def:: AdtId :: StructId ( s) = def {
221
172
let data = db. struct_data ( * s) ;
222
173
let repr = data. repr . unwrap_or_default ( ) ;
223
174
if repr. simd ( ) {
224
- return layout_of_simd_ty ( db, * s, subst, trait_env, & target) ;
175
+ return layout_of_simd_ty ( db, * s, repr . packed ( ) , subst, trait_env, & target) ;
225
176
}
226
177
} ;
227
178
return db. layout_of_adt ( * def, subst. clone ( ) , trait_env) ;
@@ -241,7 +192,7 @@ pub fn layout_of_ty_query(
241
192
valid_range : WrappingRange { start : 0 , end : 0x10FFFF } ,
242
193
} ,
243
194
) ,
244
- chalk_ir:: Scalar :: Int ( i) => scalar (
195
+ chalk_ir:: Scalar :: Int ( i) => Layout :: scalar ( dl , scalar_unit (
245
196
dl,
246
197
Primitive :: Int (
247
198
match i {
@@ -254,8 +205,8 @@ pub fn layout_of_ty_query(
254
205
} ,
255
206
true ,
256
207
) ,
257
- ) ,
258
- chalk_ir:: Scalar :: Uint ( i) => scalar (
208
+ ) ) ,
209
+ chalk_ir:: Scalar :: Uint ( i) => Layout :: scalar ( dl , scalar_unit (
259
210
dl,
260
211
Primitive :: Int (
261
212
match i {
@@ -268,16 +219,16 @@ pub fn layout_of_ty_query(
268
219
} ,
269
220
false ,
270
221
) ,
271
- ) ,
272
- chalk_ir:: Scalar :: Float ( f) => scalar (
222
+ ) ) ,
223
+ chalk_ir:: Scalar :: Float ( f) => Layout :: scalar ( dl , scalar_unit (
273
224
dl,
274
225
Primitive :: Float ( match f {
275
226
FloatTy :: F16 => Float :: F16 ,
276
227
FloatTy :: F32 => Float :: F32 ,
277
228
FloatTy :: F64 => Float :: F64 ,
278
229
FloatTy :: F128 => Float :: F128 ,
279
230
} ) ,
280
- ) ,
231
+ ) ) ,
281
232
} ,
282
233
TyKind :: Tuple ( len, tys) => {
283
234
let kind = if * len == 0 { StructKind :: AlwaysSized } else { StructKind :: MaybeUnsized } ;
@@ -293,56 +244,16 @@ pub fn layout_of_ty_query(
293
244
TyKind :: Array ( element, count) => {
294
245
let count = try_const_usize ( db, count) . ok_or ( LayoutError :: HasErrorConst ) ? as u64 ;
295
246
let element = db. layout_of_ty ( element. clone ( ) , trait_env) ?;
296
- let size = element
297
- . size
298
- . checked_mul ( count, dl)
299
- . ok_or ( LayoutError :: BadCalc ( LayoutCalculatorError :: SizeOverflow ) ) ?;
300
-
301
- let backend_repr = BackendRepr :: Memory { sized : true } ;
302
-
303
- let largest_niche = if count != 0 { element. largest_niche } else { None } ;
304
- let uninhabited = if count != 0 { element. uninhabited } else { false } ;
305
-
306
- Layout {
307
- variants : Variants :: Single { index : struct_variant_idx ( ) } ,
308
- fields : FieldsShape :: Array { stride : element. size , count } ,
309
- backend_repr,
310
- largest_niche,
311
- uninhabited,
312
- align : element. align ,
313
- size,
314
- max_repr_align : None ,
315
- unadjusted_abi_align : element. align . abi ,
316
- randomization_seed : Hash64 :: ZERO ,
317
- }
247
+ cx. calc . array_like :: < _ , _ , ( ) > ( & element, Some ( count) ) ?
318
248
}
319
249
TyKind :: Slice ( element) => {
320
250
let element = db. layout_of_ty ( element. clone ( ) , trait_env) ?;
321
- Layout {
322
- variants : Variants :: Single { index : struct_variant_idx ( ) } ,
323
- fields : FieldsShape :: Array { stride : element. size , count : 0 } ,
324
- backend_repr : BackendRepr :: Memory { sized : false } ,
325
- largest_niche : None ,
326
- uninhabited : false ,
327
- align : element. align ,
328
- size : Size :: ZERO ,
329
- max_repr_align : None ,
330
- unadjusted_abi_align : element. align . abi ,
331
- randomization_seed : Hash64 :: ZERO ,
332
- }
251
+ cx. calc . array_like :: < _ , _ , ( ) > ( & element, None ) ?
252
+ }
253
+ TyKind :: Str => {
254
+ let element = scalar_unit ( dl, Primitive :: Int ( Integer :: I8 , false ) ) ;
255
+ cx. calc . array_like :: < _ , _ , ( ) > ( & Layout :: scalar ( dl, element) , None ) ?
333
256
}
334
- TyKind :: Str => Layout {
335
- variants : Variants :: Single { index : struct_variant_idx ( ) } ,
336
- fields : FieldsShape :: Array { stride : Size :: from_bytes ( 1 ) , count : 0 } ,
337
- backend_repr : BackendRepr :: Memory { sized : false } ,
338
- largest_niche : None ,
339
- uninhabited : false ,
340
- align : dl. i8_align ,
341
- size : Size :: ZERO ,
342
- max_repr_align : None ,
343
- unadjusted_abi_align : dl. i8_align . abi ,
344
- randomization_seed : Hash64 :: ZERO ,
345
- } ,
346
257
// Potentially-wide pointers.
347
258
TyKind :: Ref ( _, _, pointee) | TyKind :: Raw ( _, pointee) => {
348
259
let mut data_ptr = scalar_unit ( dl, Primitive :: Pointer ( AddressSpace :: DATA ) ) ;
@@ -380,17 +291,12 @@ pub fn layout_of_ty_query(
380
291
} ;
381
292
382
293
// Effectively a (ptr, meta) tuple.
383
- cx . calc . scalar_pair ( data_ptr, metadata)
294
+ LayoutData :: scalar_pair ( dl , data_ptr, metadata)
384
295
}
385
- TyKind :: FnDef ( _, _) => layout_of_unit ( & cx) ?,
386
- TyKind :: Never => cx. calc . layout_of_never_type ( ) ,
387
- TyKind :: Dyn ( _) | TyKind :: Foreign ( _) => {
388
- let mut unit = layout_of_unit ( & cx) ?;
389
- match & mut unit. backend_repr {
390
- BackendRepr :: Memory { sized } => * sized = false ,
391
- _ => return Err ( LayoutError :: Unknown ) ,
392
- }
393
- unit
296
+ TyKind :: Never => LayoutData :: never_type ( dl) ,
297
+ TyKind :: FnDef ( ..) | TyKind :: Dyn ( _) | TyKind :: Foreign ( _) => {
298
+ let sized = matches ! ( kind, TyKind :: FnDef ( ..) ) ;
299
+ LayoutData :: unit ( dl, sized)
394
300
}
395
301
TyKind :: Function ( _) => {
396
302
let mut ptr = scalar_unit ( dl, Primitive :: Pointer ( dl. instruction_address_space ) ) ;
@@ -459,16 +365,6 @@ pub fn layout_of_ty_recover(
459
365
Err ( LayoutError :: RecursiveTypeWithoutIndirection )
460
366
}
461
367
462
- fn layout_of_unit ( cx : & LayoutCx < ' _ > ) -> Result < Layout , LayoutError > {
463
- cx. calc
464
- . univariant :: < RustcFieldIdx , RustcEnumVariantIdx , & & Layout > (
465
- IndexSlice :: empty ( ) ,
466
- & ReprOptions :: default ( ) ,
467
- StructKind :: AlwaysSized ,
468
- )
469
- . map_err ( Into :: into)
470
- }
471
-
472
368
fn struct_tail_erasing_lifetimes ( db : & dyn HirDatabase , pointee : Ty ) -> Ty {
473
369
match pointee. kind ( Interner ) {
474
370
TyKind :: Adt ( AdtId ( hir_def:: AdtId :: StructId ( i) ) , subst) => {
@@ -499,9 +395,5 @@ fn scalar_unit(dl: &TargetDataLayout, value: Primitive) -> Scalar {
499
395
Scalar :: Initialized { value, valid_range : WrappingRange :: full ( value. size ( dl) ) }
500
396
}
501
397
502
- fn scalar ( dl : & TargetDataLayout , value : Primitive ) -> Layout {
503
- Layout :: scalar ( dl, scalar_unit ( dl, value) )
504
- }
505
-
506
398
#[ cfg( test) ]
507
399
mod tests;
0 commit comments