@@ -6,24 +6,22 @@ use base_db::ra_salsa::Cycle;
66use chalk_ir:: { AdtId , FloatTy , IntTy , TyKind , UintTy } ;
77use hir_def:: {
88 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 ,
1111 WrappingRange ,
1212 } ,
1313 LocalFieldId , StructId ,
1414} ;
1515use la_arena:: { Idx , RawIdx } ;
1616use rustc_abi:: AddressSpace ;
17- use rustc_hashes:: Hash64 ;
18- use rustc_index:: { IndexSlice , IndexVec } ;
17+ use rustc_index:: IndexVec ;
1918
2019use triomphe:: Arc ;
2120
2221use crate :: {
2322 consteval:: try_const_usize,
2423 db:: { HirDatabase , InternedClosure } ,
2524 infer:: normalize,
26- layout:: adt:: struct_variant_idx,
2725 utils:: ClosureSubst ,
2826 Interner , ProjectionTy , Substitution , TraitEnvironment , Ty ,
2927} ;
@@ -125,82 +123,34 @@ impl<'a> LayoutCx<'a> {
125123 }
126124}
127125
128- // FIXME: move this to the `rustc_abi`.
129126fn layout_of_simd_ty (
130127 db : & dyn HirDatabase ,
131128 id : StructId ,
129+ repr_packed : bool ,
132130 subst : & Substitution ,
133131 env : Arc < TraitEnvironment > ,
134132 dl : & TargetDataLayout ,
135133) -> 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:
139135 //
140- // * #[repr(simd)] struct S(T, T, T, T);
141- // * #[repr(simd)] struct S { it: T, y: T, z: T, w: T }
142136 // * #[repr(simd)] struct S([T; 4])
143137 //
144138 // 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 ) ;
169147 } ;
170148
171- // Compute the ABI of the element type:
149+ let e_len = try_const_usize ( db , & e_len ) . ok_or ( LayoutError :: HasErrorConst ) ? as u64 ;
172150 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- } ;
176151
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) ?) )
204154}
205155
206156pub fn layout_of_ty_query (
@@ -215,13 +165,14 @@ pub fn layout_of_ty_query(
215165 let dl = & * target;
216166 let cx = LayoutCx :: new ( dl) ;
217167 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 {
219170 TyKind :: Adt ( AdtId ( def) , subst) => {
220171 if let hir_def:: AdtId :: StructId ( s) = def {
221172 let data = db. struct_data ( * s) ;
222173 let repr = data. repr . unwrap_or_default ( ) ;
223174 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) ;
225176 }
226177 } ;
227178 return db. layout_of_adt ( * def, subst. clone ( ) , trait_env) ;
@@ -241,7 +192,7 @@ pub fn layout_of_ty_query(
241192 valid_range : WrappingRange { start : 0 , end : 0x10FFFF } ,
242193 } ,
243194 ) ,
244- chalk_ir:: Scalar :: Int ( i) => scalar (
195+ chalk_ir:: Scalar :: Int ( i) => Layout :: scalar ( dl , scalar_unit (
245196 dl,
246197 Primitive :: Int (
247198 match i {
@@ -254,8 +205,8 @@ pub fn layout_of_ty_query(
254205 } ,
255206 true ,
256207 ) ,
257- ) ,
258- chalk_ir:: Scalar :: Uint ( i) => scalar (
208+ ) ) ,
209+ chalk_ir:: Scalar :: Uint ( i) => Layout :: scalar ( dl , scalar_unit (
259210 dl,
260211 Primitive :: Int (
261212 match i {
@@ -268,16 +219,16 @@ pub fn layout_of_ty_query(
268219 } ,
269220 false ,
270221 ) ,
271- ) ,
272- chalk_ir:: Scalar :: Float ( f) => scalar (
222+ ) ) ,
223+ chalk_ir:: Scalar :: Float ( f) => Layout :: scalar ( dl , scalar_unit (
273224 dl,
274225 Primitive :: Float ( match f {
275226 FloatTy :: F16 => Float :: F16 ,
276227 FloatTy :: F32 => Float :: F32 ,
277228 FloatTy :: F64 => Float :: F64 ,
278229 FloatTy :: F128 => Float :: F128 ,
279230 } ) ,
280- ) ,
231+ ) ) ,
281232 } ,
282233 TyKind :: Tuple ( len, tys) => {
283234 let kind = if * len == 0 { StructKind :: AlwaysSized } else { StructKind :: MaybeUnsized } ;
@@ -293,56 +244,16 @@ pub fn layout_of_ty_query(
293244 TyKind :: Array ( element, count) => {
294245 let count = try_const_usize ( db, count) . ok_or ( LayoutError :: HasErrorConst ) ? as u64 ;
295246 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) ) ?
318248 }
319249 TyKind :: Slice ( element) => {
320250 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 ) ?
333256 }
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- } ,
346257 // Potentially-wide pointers.
347258 TyKind :: Ref ( _, _, pointee) | TyKind :: Raw ( _, pointee) => {
348259 let mut data_ptr = scalar_unit ( dl, Primitive :: Pointer ( AddressSpace :: DATA ) ) ;
@@ -380,17 +291,12 @@ pub fn layout_of_ty_query(
380291 } ;
381292
382293 // Effectively a (ptr, meta) tuple.
383- cx . calc . scalar_pair ( data_ptr, metadata)
294+ LayoutData :: scalar_pair ( dl , data_ptr, metadata)
384295 }
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)
394300 }
395301 TyKind :: Function ( _) => {
396302 let mut ptr = scalar_unit ( dl, Primitive :: Pointer ( dl. instruction_address_space ) ) ;
@@ -459,16 +365,6 @@ pub fn layout_of_ty_recover(
459365 Err ( LayoutError :: RecursiveTypeWithoutIndirection )
460366}
461367
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-
472368fn struct_tail_erasing_lifetimes ( db : & dyn HirDatabase , pointee : Ty ) -> Ty {
473369 match pointee. kind ( Interner ) {
474370 TyKind :: Adt ( AdtId ( hir_def:: AdtId :: StructId ( i) ) , subst) => {
@@ -499,9 +395,5 @@ fn scalar_unit(dl: &TargetDataLayout, value: Primitive) -> Scalar {
499395 Scalar :: Initialized { value, valid_range : WrappingRange :: full ( value. size ( dl) ) }
500396}
501397
502- fn scalar ( dl : & TargetDataLayout , value : Primitive ) -> Layout {
503- Layout :: scalar ( dl, scalar_unit ( dl, value) )
504- }
505-
506398#[ cfg( test) ]
507399mod tests;
0 commit comments