@@ -95,7 +95,11 @@ fn check_struct(tcx: TyCtxt<'_>, def_id: LocalDefId) {
9595 def. destructor ( tcx) ; // force the destructor to be evaluated
9696
9797 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+ }
99103 }
100104
101105 check_transparent ( tcx, def) ;
@@ -1393,6 +1397,54 @@ fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) {
13931397 }
13941398}
13951399
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+
13961448pub ( super ) fn check_packed ( tcx : TyCtxt < ' _ > , sp : Span , def : ty:: AdtDef < ' _ > ) {
13971449 let repr = def. repr ( ) ;
13981450 if repr. packed ( ) {
0 commit comments