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