@@ -95,7 +95,11 @@ fn check_struct(tcx: TyCtxt<'_>, def_id: LocalDefId) {
95
95
def. destructor ( tcx) ; // force the destructor to be evaluated
96
96
97
97
if def. repr ( ) . simd ( ) {
98
- check_simd ( tcx, span, def_id) ;
98
+ if def. repr ( ) . scalable ( ) {
99
+ check_scalable_simd ( tcx, span, def_id) ;
100
+ } else {
101
+ check_simd ( tcx, span, def_id) ;
102
+ }
99
103
}
100
104
101
105
check_transparent ( tcx, def) ;
@@ -1393,6 +1397,54 @@ fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) {
1393
1397
}
1394
1398
}
1395
1399
1400
+ fn check_scalable_simd ( tcx : TyCtxt < ' _ > , span : Span , def_id : LocalDefId ) {
1401
+ let ty = tcx. type_of ( def_id) . instantiate_identity ( ) ;
1402
+ let ty:: Adt ( def, args) = ty. kind ( ) else { return } ;
1403
+ if !def. is_struct ( ) {
1404
+ tcx. dcx ( ) . delayed_bug ( "`repr(scalable)` applied to non-struct" ) ;
1405
+ return ;
1406
+ }
1407
+
1408
+ let fields = & def. non_enum_variant ( ) . fields ;
1409
+ match fields. len ( ) {
1410
+ 0 => {
1411
+ let mut err =
1412
+ tcx. dcx ( ) . struct_span_err ( span, "scalable vectors must have a single field" ) ;
1413
+ err. help ( "scalable vector types' only field must be slice of a primitive scalar type" ) ;
1414
+ err. emit ( ) ;
1415
+ return ;
1416
+ }
1417
+ 1 => { }
1418
+ 2 .. => {
1419
+ tcx. dcx ( ) . struct_span_err ( span, "scalable vectors cannot have multiple fields" ) . emit ( ) ;
1420
+ }
1421
+ }
1422
+
1423
+ let array_field = & fields[ FieldIdx :: ZERO ] ;
1424
+ let array_ty = array_field. ty ( tcx, args) ;
1425
+ let ty:: Slice ( element_ty) = array_ty. kind ( ) else {
1426
+ let mut err =
1427
+ tcx. dcx ( ) . struct_span_err ( span, "the field of a scalable vector type must be a slice" ) ;
1428
+ err. span_label ( tcx. def_span ( array_field. did ) , "not a slice" ) ;
1429
+ err. emit ( ) ;
1430
+ return ;
1431
+ } ;
1432
+
1433
+ // Check that `element_ty` only uses types valid in the lanes of a scalable vector register:
1434
+ // scalar types which directly match a "machine" type - e.g. integers, floats, bools, thin ptrs.
1435
+ match element_ty. kind ( ) {
1436
+ ty:: Int ( _) | ty:: Uint ( _) | ty:: Float ( _) | ty:: RawPtr ( _, _) | ty:: Bool => ( ) ,
1437
+ _ => {
1438
+ let mut err = tcx. dcx ( ) . struct_span_err (
1439
+ span,
1440
+ "element type of a scalable vector must be a primitive scalar" ,
1441
+ ) ;
1442
+ err. help ( "only `u*`, `i*`, `f*`, `*const`, `*mut` and `bool` types are accepted" ) ;
1443
+ err. emit ( ) ;
1444
+ }
1445
+ }
1446
+ }
1447
+
1396
1448
pub ( super ) fn check_packed ( tcx : TyCtxt < ' _ > , sp : Span , def : ty:: AdtDef < ' _ > ) {
1397
1449
let repr = def. repr ( ) ;
1398
1450
if repr. packed ( ) {
0 commit comments