1
- use crate :: gather_locals:: { DeclContext , DeclOrigin } ;
1
+ use crate :: gather_locals:: DeclOrigin ;
2
2
use crate :: { errors, FnCtxt , RawTy } ;
3
3
use rustc_ast as ast;
4
4
use rustc_data_structures:: fx:: FxHashMap ;
@@ -79,10 +79,10 @@ struct TopInfo<'tcx> {
79
79
}
80
80
81
81
#[ derive( Copy , Clone ) ]
82
- struct PatInfo < ' tcx > {
82
+ struct PatInfo < ' tcx , ' a > {
83
83
binding_mode : BindingMode ,
84
84
top_info : TopInfo < ' tcx > ,
85
- decl_ctxt : Option < DeclContext > ,
85
+ decl_origin : Option < DeclOrigin < ' a > > ,
86
86
}
87
87
88
88
impl < ' tcx > FnCtxt < ' _ , ' tcx > {
@@ -149,10 +149,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
149
149
expected : Ty < ' tcx > ,
150
150
span : Option < Span > ,
151
151
origin_expr : Option < & ' tcx hir:: Expr < ' tcx > > ,
152
- decl_ctxt : Option < DeclContext > ,
152
+ decl_origin : Option < DeclOrigin < ' tcx > > ,
153
153
) {
154
154
let info = TopInfo { expected, origin_expr, span } ;
155
- let pat_info = PatInfo { binding_mode : INITIAL_BM , top_info : info, decl_ctxt } ;
155
+ let pat_info = PatInfo { binding_mode : INITIAL_BM , top_info : info, decl_origin } ;
156
156
self . check_pat ( pat, expected, pat_info) ;
157
157
}
158
158
@@ -162,8 +162,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
162
162
/// Outside of this module, `check_pat_top` should always be used.
163
163
/// Conversely, inside this module, `check_pat_top` should never be used.
164
164
#[ instrument( level = "debug" , skip( self , pat_info) ) ]
165
- fn check_pat ( & self , pat : & ' tcx Pat < ' tcx > , expected : Ty < ' tcx > , pat_info : PatInfo < ' tcx > ) {
166
- let PatInfo { binding_mode : def_bm, top_info : ti, decl_ctxt } = pat_info;
165
+ fn check_pat ( & self , pat : & ' tcx Pat < ' tcx > , expected : Ty < ' tcx > , pat_info : PatInfo < ' tcx , ' _ > ) {
166
+ let PatInfo { binding_mode : def_bm, top_info : ti, decl_origin } = pat_info;
167
167
let path_res = match & pat. kind {
168
168
PatKind :: Path ( qpath) => {
169
169
Some ( self . resolve_ty_and_res_fully_qualified_call ( qpath, pat. hir_id , pat. span ) )
@@ -183,15 +183,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
183
183
var_id,
184
184
sub,
185
185
expected,
186
- PatInfo { binding_mode : def_bm, top_info : ti, decl_ctxt } ,
186
+ PatInfo { binding_mode : def_bm, top_info : ti, decl_origin } ,
187
187
) ,
188
188
PatKind :: TupleStruct ( ref qpath, subpats, ddpos) => self . check_pat_tuple_struct (
189
189
pat,
190
190
qpath,
191
191
subpats,
192
192
ddpos,
193
193
expected,
194
- PatInfo { binding_mode : def_bm, top_info : ti, decl_ctxt } ,
194
+ PatInfo { binding_mode : def_bm, top_info : ti, decl_origin } ,
195
195
) ,
196
196
PatKind :: Path ( ref qpath) => {
197
197
self . check_pat_path ( pat, qpath, path_res. unwrap ( ) , expected, ti)
@@ -202,14 +202,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
202
202
fields,
203
203
has_rest_pat,
204
204
expected,
205
- PatInfo { binding_mode : def_bm, top_info : ti, decl_ctxt } ,
205
+ PatInfo { binding_mode : def_bm, top_info : ti, decl_origin } ,
206
206
) ,
207
207
PatKind :: Or ( pats) => {
208
208
for pat in pats {
209
209
self . check_pat (
210
210
pat,
211
211
expected,
212
- PatInfo { binding_mode : def_bm, top_info : ti, decl_ctxt } ,
212
+ PatInfo { binding_mode : def_bm, top_info : ti, decl_origin } ,
213
213
) ;
214
214
}
215
215
expected
@@ -219,28 +219,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
219
219
elements,
220
220
ddpos,
221
221
expected,
222
- PatInfo { binding_mode : def_bm, top_info : ti, decl_ctxt } ,
222
+ PatInfo { binding_mode : def_bm, top_info : ti, decl_origin } ,
223
223
) ,
224
224
PatKind :: Box ( inner) => self . check_pat_box (
225
225
pat. span ,
226
226
inner,
227
227
expected,
228
- PatInfo { binding_mode : def_bm, top_info : ti, decl_ctxt } ,
228
+ PatInfo { binding_mode : def_bm, top_info : ti, decl_origin } ,
229
229
) ,
230
230
PatKind :: Ref ( inner, mutbl) => self . check_pat_ref (
231
231
pat,
232
232
inner,
233
233
mutbl,
234
234
expected,
235
- PatInfo { binding_mode : def_bm, top_info : ti, decl_ctxt } ,
235
+ PatInfo { binding_mode : def_bm, top_info : ti, decl_origin } ,
236
236
) ,
237
237
PatKind :: Slice ( before, slice, after) => self . check_pat_slice (
238
238
pat. span ,
239
239
before,
240
240
slice,
241
241
after,
242
242
expected,
243
- PatInfo { binding_mode : def_bm, top_info : ti, decl_ctxt } ,
243
+ PatInfo { binding_mode : def_bm, top_info : ti, decl_origin } ,
244
244
) ,
245
245
} ;
246
246
@@ -622,9 +622,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
622
622
var_id : HirId ,
623
623
sub : Option < & ' tcx Pat < ' tcx > > ,
624
624
expected : Ty < ' tcx > ,
625
- pat_info : PatInfo < ' tcx > ,
625
+ pat_info : PatInfo < ' tcx , ' _ > ,
626
626
) -> Ty < ' tcx > {
627
- let PatInfo { binding_mode : def_bm, top_info : ti, decl_ctxt } = pat_info;
627
+ let PatInfo { binding_mode : def_bm, top_info : ti, decl_origin } = pat_info;
628
628
629
629
// Determine the binding mode...
630
630
let bm = match ba {
@@ -663,7 +663,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
663
663
}
664
664
665
665
if let Some ( p) = sub {
666
- self . check_pat ( p, expected, PatInfo { binding_mode : def_bm, top_info : ti, decl_ctxt } ) ;
666
+ self . check_pat (
667
+ p,
668
+ expected,
669
+ PatInfo { binding_mode : def_bm, top_info : ti, decl_origin } ,
670
+ ) ;
667
671
}
668
672
669
673
local_ty
@@ -886,9 +890,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
886
890
fields : & ' tcx [ hir:: PatField < ' tcx > ] ,
887
891
has_rest_pat : bool ,
888
892
expected : Ty < ' tcx > ,
889
- pat_info : PatInfo < ' tcx > ,
893
+ pat_info : PatInfo < ' tcx , ' _ > ,
890
894
) -> Ty < ' tcx > {
891
- let PatInfo { binding_mode : def_bm, top_info : ti, decl_ctxt } = pat_info;
895
+ let PatInfo { binding_mode : def_bm, top_info : ti, decl_origin } = pat_info;
892
896
893
897
// Resolve the path and check the definition for errors.
894
898
let ( variant, pat_ty) = match self . check_struct_path ( qpath, pat. hir_id ) {
@@ -900,7 +904,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
900
904
self . check_pat (
901
905
field. pat ,
902
906
err,
903
- PatInfo { binding_mode : def_bm, top_info : ti, decl_ctxt } ,
907
+ PatInfo { binding_mode : def_bm, top_info : ti, decl_origin } ,
904
908
) ;
905
909
}
906
910
return err;
@@ -917,7 +921,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
917
921
variant,
918
922
fields,
919
923
has_rest_pat,
920
- PatInfo { binding_mode : def_bm, top_info : ti, decl_ctxt } ,
924
+ PatInfo { binding_mode : def_bm, top_info : ti, decl_origin } ,
921
925
) {
922
926
pat_ty
923
927
} else {
@@ -1083,16 +1087,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1083
1087
subpats : & ' tcx [ Pat < ' tcx > ] ,
1084
1088
ddpos : hir:: DotDotPos ,
1085
1089
expected : Ty < ' tcx > ,
1086
- pat_info : PatInfo < ' tcx > ,
1090
+ pat_info : PatInfo < ' tcx , ' _ > ,
1087
1091
) -> Ty < ' tcx > {
1088
- let PatInfo { binding_mode : def_bm, top_info : ti, decl_ctxt } = pat_info;
1092
+ let PatInfo { binding_mode : def_bm, top_info : ti, decl_origin } = pat_info;
1089
1093
let tcx = self . tcx ;
1090
1094
let on_error = |e| {
1091
1095
for pat in subpats {
1092
1096
self . check_pat (
1093
1097
pat,
1094
1098
Ty :: new_error ( tcx, e) ,
1095
- PatInfo { binding_mode : def_bm, top_info : ti, decl_ctxt } ,
1099
+ PatInfo { binding_mode : def_bm, top_info : ti, decl_origin } ,
1096
1100
) ;
1097
1101
}
1098
1102
} ;
@@ -1162,7 +1166,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1162
1166
self . check_pat (
1163
1167
subpat,
1164
1168
field_ty,
1165
- PatInfo { binding_mode : def_bm, top_info : ti, decl_ctxt } ,
1169
+ PatInfo { binding_mode : def_bm, top_info : ti, decl_origin } ,
1166
1170
) ;
1167
1171
1168
1172
self . tcx . check_stability (
@@ -1347,7 +1351,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1347
1351
elements : & ' tcx [ Pat < ' tcx > ] ,
1348
1352
ddpos : hir:: DotDotPos ,
1349
1353
expected : Ty < ' tcx > ,
1350
- pat_info : PatInfo < ' tcx > ,
1354
+ pat_info : PatInfo < ' tcx , ' _ > ,
1351
1355
) -> Ty < ' tcx > {
1352
1356
let tcx = self . tcx ;
1353
1357
let mut expected_len = elements. len ( ) ;
@@ -1394,7 +1398,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1394
1398
variant : & ' tcx ty:: VariantDef ,
1395
1399
fields : & ' tcx [ hir:: PatField < ' tcx > ] ,
1396
1400
has_rest_pat : bool ,
1397
- pat_info : PatInfo < ' tcx > ,
1401
+ pat_info : PatInfo < ' tcx , ' _ > ,
1398
1402
) -> bool {
1399
1403
let tcx = self . tcx ;
1400
1404
@@ -2004,7 +2008,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2004
2008
span : Span ,
2005
2009
inner : & ' tcx Pat < ' tcx > ,
2006
2010
expected : Ty < ' tcx > ,
2007
- pat_info : PatInfo < ' tcx > ,
2011
+ pat_info : PatInfo < ' tcx , ' _ > ,
2008
2012
) -> Ty < ' tcx > {
2009
2013
let tcx = self . tcx ;
2010
2014
let ( box_ty, inner_ty) = match self . check_dereferenceable ( span, expected, inner) {
@@ -2035,7 +2039,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2035
2039
inner : & ' tcx Pat < ' tcx > ,
2036
2040
mutbl : hir:: Mutability ,
2037
2041
expected : Ty < ' tcx > ,
2038
- pat_info : PatInfo < ' tcx > ,
2042
+ pat_info : PatInfo < ' tcx , ' _ > ,
2039
2043
) -> Ty < ' tcx > {
2040
2044
let tcx = self . tcx ;
2041
2045
let expected = self . shallow_resolve ( expected) ;
@@ -2139,9 +2143,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2139
2143
///
2140
2144
/// If we're in an irrefutable pattern we prefer the array impl candidate given that
2141
2145
/// the slice impl candidate would be be rejected anyway (if no ambiguity existed).
2142
- fn pat_is_irrefutable ( & self , decl_ctxt : Option < DeclContext > ) -> bool {
2143
- if let Some ( decl_ctxt) = decl_ctxt {
2144
- !decl_ctxt. has_else && matches ! ( decl_ctxt. origin, DeclOrigin :: LocalDecl )
2146
+ fn pat_is_irrefutable ( & self , decl_origin : Option < DeclOrigin < ' _ > > ) -> bool {
2147
+ if let Some ( decl_origin) = decl_origin {
2148
+ decl_origin. try_get_els ( ) . is_none ( )
2149
+ && matches ! ( decl_origin, DeclOrigin :: LocalDecl { .. } )
2145
2150
} else {
2146
2151
false
2147
2152
}
@@ -2164,11 +2169,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2164
2169
slice : Option < & ' tcx Pat < ' tcx > > ,
2165
2170
after : & ' tcx [ Pat < ' tcx > ] ,
2166
2171
expected : Ty < ' tcx > ,
2167
- pat_info : PatInfo < ' tcx > ,
2172
+ pat_info : PatInfo < ' tcx , ' _ > ,
2168
2173
) -> Ty < ' tcx > {
2169
2174
// If the pattern is irrefutable and `expected` is an infer ty, we try to equate it
2170
2175
// to an array if the given pattern allows it. See issue #76342
2171
- if self . pat_is_irrefutable ( pat_info. decl_ctxt ) && expected. is_ty_var ( ) {
2176
+ if self . pat_is_irrefutable ( pat_info. decl_origin ) && expected. is_ty_var ( ) {
2172
2177
if let Some ( resolved_arr_ty) =
2173
2178
self . try_resolve_slice_ty_to_array_ty ( before, slice, span)
2174
2179
{
0 commit comments