@@ -52,8 +52,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
52
52
def_bm : ty:: BindingMode ,
53
53
discrim_span : Option < Span > ,
54
54
) {
55
- let tcx = self . tcx ;
56
-
57
55
debug ! ( "check_pat_walk(pat={:?},expected={:?},def_bm={:?})" , pat, expected, def_bm) ;
58
56
59
57
let path_resolution = match & pat. node {
@@ -114,77 +112,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
114
112
self . check_pat_ref ( pat, inner, mutbl, expected, def_bm, discrim_span)
115
113
}
116
114
PatKind :: Slice ( ref before, ref slice, ref after) => {
117
- let expected_ty = self . structurally_resolved_type ( pat. span , expected) ;
118
- let ( inner_ty, slice_ty) = match expected_ty. sty {
119
- ty:: Array ( inner_ty, size) => {
120
- if let Some ( size) = size. try_eval_usize ( tcx, self . param_env ) {
121
- let min_len = before. len ( ) as u64 + after. len ( ) as u64 ;
122
- if slice. is_none ( ) {
123
- if min_len != size {
124
- struct_span_err ! (
125
- tcx. sess, pat. span, E0527 ,
126
- "pattern requires {} elements but array has {}" ,
127
- min_len, size)
128
- . span_label ( pat. span , format ! ( "expected {} elements" , size) )
129
- . emit ( ) ;
130
- }
131
- ( inner_ty, tcx. types . err )
132
- } else if let Some ( rest) = size. checked_sub ( min_len) {
133
- ( inner_ty, tcx. mk_array ( inner_ty, rest) )
134
- } else {
135
- struct_span_err ! ( tcx. sess, pat. span, E0528 ,
136
- "pattern requires at least {} elements but array has {}" ,
137
- min_len, size)
138
- . span_label ( pat. span ,
139
- format ! ( "pattern cannot match array of {} elements" , size) )
140
- . emit ( ) ;
141
- ( inner_ty, tcx. types . err )
142
- }
143
- } else {
144
- struct_span_err ! (
145
- tcx. sess,
146
- pat. span,
147
- E0730 ,
148
- "cannot pattern-match on an array without a fixed length" ,
149
- ) . emit ( ) ;
150
- ( inner_ty, tcx. types . err )
151
- }
152
- }
153
- ty:: Slice ( inner_ty) => ( inner_ty, expected_ty) ,
154
- _ => {
155
- if !expected_ty. references_error ( ) {
156
- let mut err = struct_span_err ! (
157
- tcx. sess, pat. span, E0529 ,
158
- "expected an array or slice, found `{}`" ,
159
- expected_ty) ;
160
- if let ty:: Ref ( _, ty, _) = expected_ty. sty {
161
- match ty. sty {
162
- ty:: Array ( ..) | ty:: Slice ( ..) => {
163
- err. help ( "the semantics of slice patterns changed \
164
- recently; see issue #62254") ;
165
- }
166
- _ => { }
167
- }
168
- }
169
-
170
- err. span_label ( pat. span ,
171
- format ! ( "pattern cannot match with input type `{}`" , expected_ty)
172
- ) . emit ( ) ;
173
- }
174
- ( tcx. types . err , tcx. types . err )
175
- }
176
- } ;
177
-
178
- for elt in before {
179
- self . check_pat_walk ( & elt, inner_ty, def_bm, discrim_span) ;
180
- }
181
- if let Some ( ref slice) = * slice {
182
- self . check_pat_walk ( & slice, slice_ty, def_bm, discrim_span) ;
183
- }
184
- for elt in after {
185
- self . check_pat_walk ( & elt, inner_ty, def_bm, discrim_span) ;
186
- }
187
- expected_ty
115
+ let slice = slice. as_deref ( ) ;
116
+ self . check_pat_slice ( pat. span , before, slice, after, expected, def_bm, discrim_span)
188
117
}
189
118
} ;
190
119
@@ -1070,4 +999,88 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1070
999
tcx. types . err
1071
1000
}
1072
1001
}
1002
+
1003
+ fn check_pat_slice (
1004
+ & self ,
1005
+ span : Span ,
1006
+ before : & ' tcx [ P < hir:: Pat > ] ,
1007
+ slice : Option < & ' tcx hir:: Pat > ,
1008
+ after : & ' tcx [ P < hir:: Pat > ] ,
1009
+ expected : Ty < ' tcx > ,
1010
+ def_bm : ty:: BindingMode ,
1011
+ discrim_span : Option < Span > ,
1012
+ ) -> Ty < ' tcx > {
1013
+ let tcx = self . tcx ;
1014
+ let expected_ty = self . structurally_resolved_type ( span, expected) ;
1015
+ let ( inner_ty, slice_ty) = match expected_ty. sty {
1016
+ ty:: Array ( inner_ty, size) => {
1017
+ if let Some ( size) = size. try_eval_usize ( tcx, self . param_env ) {
1018
+ let min_len = before. len ( ) as u64 + after. len ( ) as u64 ;
1019
+ if slice. is_none ( ) {
1020
+ if min_len != size {
1021
+ struct_span_err ! (
1022
+ tcx. sess, span, E0527 ,
1023
+ "pattern requires {} elements but array has {}" ,
1024
+ min_len, size
1025
+ )
1026
+ . span_label ( span, format ! ( "expected {} elements" , size) )
1027
+ . emit ( ) ;
1028
+ }
1029
+ ( inner_ty, tcx. types . err )
1030
+ } else if let Some ( rest) = size. checked_sub ( min_len) {
1031
+ ( inner_ty, tcx. mk_array ( inner_ty, rest) )
1032
+ } else {
1033
+ let msg = format ! ( "pattern cannot match array of {} elements" , size) ;
1034
+ struct_span_err ! (
1035
+ tcx. sess, span, E0528 ,
1036
+ "pattern requires at least {} elements but array has {}" ,
1037
+ min_len, size
1038
+ )
1039
+ . span_label ( span, msg)
1040
+ . emit ( ) ;
1041
+ ( inner_ty, tcx. types . err )
1042
+ }
1043
+ } else {
1044
+ struct_span_err ! (
1045
+ tcx. sess, span, E0730 ,
1046
+ "cannot pattern-match on an array without a fixed length" ,
1047
+ )
1048
+ . emit ( ) ;
1049
+ ( inner_ty, tcx. types . err )
1050
+ }
1051
+ }
1052
+ ty:: Slice ( inner_ty) => ( inner_ty, expected_ty) ,
1053
+ _ => {
1054
+ if !expected_ty. references_error ( ) {
1055
+ let mut err = struct_span_err ! (
1056
+ tcx. sess, span, E0529 ,
1057
+ "expected an array or slice, found `{}`" ,
1058
+ expected_ty
1059
+ ) ;
1060
+ if let ty:: Ref ( _, ty, _) = expected_ty. sty {
1061
+ if let ty:: Array ( ..) | ty:: Slice ( ..) = ty. sty {
1062
+ err. help ( "the semantics of slice patterns changed \
1063
+ recently; see issue #62254") ;
1064
+ }
1065
+ }
1066
+
1067
+ let msg = format ! ( "pattern cannot match with input type `{}`" , expected_ty) ;
1068
+ err. span_label ( span, msg) ;
1069
+ err. emit ( ) ;
1070
+ }
1071
+ ( tcx. types . err , tcx. types . err )
1072
+ }
1073
+ } ;
1074
+
1075
+ for elt in before {
1076
+ self . check_pat_walk ( & elt, inner_ty, def_bm, discrim_span) ;
1077
+ }
1078
+ if let Some ( slice) = slice {
1079
+ self . check_pat_walk ( & slice, slice_ty, def_bm, discrim_span) ;
1080
+ }
1081
+ for elt in after {
1082
+ self . check_pat_walk ( & elt, inner_ty, def_bm, discrim_span) ;
1083
+ }
1084
+ expected_ty
1085
+ }
1073
1086
}
0 commit comments