@@ -1064,20 +1064,29 @@ fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) {
1064
1064
struct_span_code_err ! ( tcx. dcx( ) , sp, E0075 , "SIMD vector cannot be empty" ) . emit ( ) ;
1065
1065
return ;
1066
1066
}
1067
- let e = fields[ FieldIdx :: ZERO ] . ty ( tcx, args) ;
1068
- if !fields. iter ( ) . all ( |f| f. ty ( tcx, args) == e) {
1069
- struct_span_code_err ! ( tcx. dcx( ) , sp, E0076 , "SIMD vector should be homogeneous" )
1070
- . with_span_label ( sp, "SIMD elements must have the same type" )
1067
+
1068
+ let array_field = & fields[ FieldIdx :: ZERO ] ;
1069
+ let array_ty = array_field. ty ( tcx, args) ;
1070
+ let ty:: Array ( element_ty, len_const) = array_ty. kind ( ) else {
1071
+ struct_span_code_err ! (
1072
+ tcx. dcx( ) ,
1073
+ sp,
1074
+ E0076 ,
1075
+ "SIMD vector's only field must be an array"
1076
+ )
1077
+ . with_span_label ( tcx. def_span ( array_field. did ) , "not an array" )
1078
+ . emit ( ) ;
1079
+ return ;
1080
+ } ;
1081
+
1082
+ if let Some ( second_field) = fields. get ( FieldIdx :: from_u32 ( 1 ) ) {
1083
+ struct_span_code_err ! ( tcx. dcx( ) , sp, E0075 , "SIMD vector cannot have multiple fields" )
1084
+ . with_span_label ( tcx. def_span ( second_field. did ) , "excess field" )
1071
1085
. emit ( ) ;
1072
1086
return ;
1073
1087
}
1074
1088
1075
- let len = if let ty:: Array ( _ty, c) = e. kind ( ) {
1076
- c. try_eval_target_usize ( tcx, tcx. param_env ( def. did ( ) ) )
1077
- } else {
1078
- Some ( fields. len ( ) as u64 )
1079
- } ;
1080
- if let Some ( len) = len {
1089
+ if let Some ( len) = len_const. try_eval_target_usize ( tcx, tcx. param_env ( def. did ( ) ) ) {
1081
1090
if len == 0 {
1082
1091
struct_span_code_err ! ( tcx. dcx( ) , sp, E0075 , "SIMD vector cannot be empty" ) . emit ( ) ;
1083
1092
return ;
@@ -1097,16 +1106,9 @@ fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) {
1097
1106
// These are scalar types which directly match a "machine" type
1098
1107
// Yes: Integers, floats, "thin" pointers
1099
1108
// No: char, "fat" pointers, compound types
1100
- match e. kind ( ) {
1101
- ty:: Param ( _) => ( ) , // pass struct<T>(T, T, T, T) through, let monomorphization catch errors
1102
- ty:: Int ( _) | ty:: Uint ( _) | ty:: Float ( _) | ty:: RawPtr ( _, _) => ( ) , // struct(u8, u8, u8, u8) is ok
1103
- ty:: Array ( t, _) if matches ! ( t. kind( ) , ty:: Param ( _) ) => ( ) , // pass struct<T>([T; N]) through, let monomorphization catch errors
1104
- ty:: Array ( t, _clen)
1105
- if matches ! (
1106
- t. kind( ) ,
1107
- ty:: Int ( _) | ty:: Uint ( _) | ty:: Float ( _) | ty:: RawPtr ( _, _)
1108
- ) =>
1109
- { /* struct([f32; 4]) is ok */ }
1109
+ match element_ty. kind ( ) {
1110
+ ty:: Param ( _) => ( ) , // pass struct<T>([T; 4]) through, let monomorphization catch errors
1111
+ ty:: Int ( _) | ty:: Uint ( _) | ty:: Float ( _) | ty:: RawPtr ( _, _) => ( ) , // struct([u8; 4]) is ok
1110
1112
_ => {
1111
1113
struct_span_code_err ! (
1112
1114
tcx. dcx( ) ,
0 commit comments