@@ -1012,59 +1012,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1012
1012
let expected_ty = self . structurally_resolved_type ( span, expected) ;
1013
1013
let ( inner_ty, slice_ty) = match expected_ty. sty {
1014
1014
ty:: Array ( inner_ty, size) => {
1015
- if let Some ( size) = size. try_eval_usize ( tcx, self . param_env ) {
1015
+ let slice_ty = if let Some ( size) = size. try_eval_usize ( tcx, self . param_env ) {
1016
1016
let min_len = before. len ( ) as u64 + after. len ( ) as u64 ;
1017
1017
if slice. is_none ( ) {
1018
1018
if min_len != size {
1019
- struct_span_err ! (
1020
- tcx. sess, span, E0527 ,
1021
- "pattern requires {} elements but array has {}" ,
1022
- min_len, size
1023
- )
1024
- . span_label ( span, format ! ( "expected {} elements" , size) )
1025
- . emit ( ) ;
1019
+ self . error_scrutinee_inconsistent_length ( span, min_len, size)
1026
1020
}
1027
- ( inner_ty , tcx. types . err )
1021
+ tcx. types . err
1028
1022
} else if let Some ( rest) = size. checked_sub ( min_len) {
1029
- ( inner_ty , tcx. mk_array ( inner_ty, rest) )
1023
+ tcx. mk_array ( inner_ty, rest)
1030
1024
} else {
1031
- let msg = format ! ( "pattern cannot match array of {} elements" , size) ;
1032
- struct_span_err ! (
1033
- tcx. sess, span, E0528 ,
1034
- "pattern requires at least {} elements but array has {}" ,
1035
- min_len, size
1036
- )
1037
- . span_label ( span, msg)
1038
- . emit ( ) ;
1039
- ( inner_ty, tcx. types . err )
1025
+ self . error_scrutinee_with_rest_inconsistent_length ( span, min_len, size) ;
1026
+ tcx. types . err
1040
1027
}
1041
1028
} else {
1042
- struct_span_err ! (
1043
- tcx. sess, span, E0730 ,
1044
- "cannot pattern-match on an array without a fixed length" ,
1045
- )
1046
- . emit ( ) ;
1047
- ( inner_ty, tcx. types . err )
1048
- }
1029
+ self . error_scrutinee_unfixed_length ( span) ;
1030
+ tcx. types . err
1031
+ } ;
1032
+ ( inner_ty, slice_ty)
1049
1033
}
1050
1034
ty:: Slice ( inner_ty) => ( inner_ty, expected_ty) ,
1051
1035
_ => {
1052
1036
if !expected_ty. references_error ( ) {
1053
- let mut err = struct_span_err ! (
1054
- tcx. sess, span, E0529 ,
1055
- "expected an array or slice, found `{}`" ,
1056
- expected_ty
1057
- ) ;
1058
- if let ty:: Ref ( _, ty, _) = expected_ty. sty {
1059
- if let ty:: Array ( ..) | ty:: Slice ( ..) = ty. sty {
1060
- err. help ( "the semantics of slice patterns changed \
1061
- recently; see issue #62254") ;
1062
- }
1063
- }
1064
-
1065
- let msg = format ! ( "pattern cannot match with input type `{}`" , expected_ty) ;
1066
- err. span_label ( span, msg) ;
1067
- err. emit ( ) ;
1037
+ self . error_expected_array_or_slice ( span, expected_ty) ;
1068
1038
}
1069
1039
( tcx. types . err , tcx. types . err )
1070
1040
}
@@ -1081,4 +1051,47 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1081
1051
}
1082
1052
expected_ty
1083
1053
}
1054
+
1055
+ fn error_scrutinee_inconsistent_length ( & self , span : Span , min_len : u64 , size : u64 ) {
1056
+ struct_span_err ! (
1057
+ self . tcx. sess, span, E0527 ,
1058
+ "pattern requires {} elements but array has {}" ,
1059
+ min_len, size
1060
+ )
1061
+ . span_label ( span, format ! ( "expected {} elements" , size) )
1062
+ . emit ( ) ;
1063
+ }
1064
+
1065
+ fn error_scrutinee_with_rest_inconsistent_length ( & self , span : Span , min_len : u64 , size : u64 ) {
1066
+ struct_span_err ! (
1067
+ self . tcx. sess, span, E0528 ,
1068
+ "pattern requires at least {} elements but array has {}" ,
1069
+ min_len, size
1070
+ )
1071
+ . span_label ( span, format ! ( "pattern cannot match array of {} elements" , size) )
1072
+ . emit ( ) ;
1073
+ }
1074
+
1075
+ fn error_scrutinee_unfixed_length ( & self , span : Span ) {
1076
+ struct_span_err ! (
1077
+ self . tcx. sess, span, E0730 ,
1078
+ "cannot pattern-match on an array without a fixed length" ,
1079
+ )
1080
+ . emit ( ) ;
1081
+ }
1082
+
1083
+ fn error_expected_array_or_slice ( & self , span : Span , expected_ty : Ty < ' tcx > ) {
1084
+ let mut err = struct_span_err ! (
1085
+ self . tcx. sess, span, E0529 ,
1086
+ "expected an array or slice, found `{}`" ,
1087
+ expected_ty
1088
+ ) ;
1089
+ if let ty:: Ref ( _, ty, _) = expected_ty. sty {
1090
+ if let ty:: Array ( ..) | ty:: Slice ( ..) = ty. sty {
1091
+ err. help ( "the semantics of slice patterns changed recently; see issue #62254" ) ;
1092
+ }
1093
+ }
1094
+ err. span_label ( span, format ! ( "pattern cannot match with input type `{}`" , expected_ty) ) ;
1095
+ err. emit ( ) ;
1096
+ }
1084
1097
}
0 commit comments