1- use crate :: gather_locals:: { DeclContext , DeclOrigin } ;
1+ use crate :: gather_locals:: DeclOrigin ;
22use crate :: { errors, FnCtxt , RawTy } ;
33use rustc_ast as ast;
44use rustc_data_structures:: fx:: FxHashMap ;
@@ -79,10 +79,10 @@ struct TopInfo<'tcx> {
7979}
8080
8181#[ derive( Copy , Clone ) ]
82- struct PatInfo < ' tcx > {
82+ struct PatInfo < ' tcx , ' a > {
8383 binding_mode : BindingMode ,
8484 top_info : TopInfo < ' tcx > ,
85- decl_ctxt : Option < DeclContext > ,
85+ decl_origin : Option < DeclOrigin < ' a > > ,
8686}
8787
8888impl < ' tcx > FnCtxt < ' _ , ' tcx > {
@@ -149,10 +149,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
149149 expected : Ty < ' tcx > ,
150150 span : Option < Span > ,
151151 origin_expr : Option < & ' tcx hir:: Expr < ' tcx > > ,
152- decl_ctxt : Option < DeclContext > ,
152+ decl_origin : Option < DeclOrigin < ' tcx > > ,
153153 ) {
154154 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 } ;
156156 self . check_pat ( pat, expected, pat_info) ;
157157 }
158158
@@ -162,8 +162,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
162162 /// Outside of this module, `check_pat_top` should always be used.
163163 /// Conversely, inside this module, `check_pat_top` should never be used.
164164 #[ 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;
167167 let path_res = match & pat. kind {
168168 PatKind :: Path ( qpath) => {
169169 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> {
183183 var_id,
184184 sub,
185185 expected,
186- PatInfo { binding_mode : def_bm, top_info : ti, decl_ctxt } ,
186+ PatInfo { binding_mode : def_bm, top_info : ti, decl_origin } ,
187187 ) ,
188188 PatKind :: TupleStruct ( ref qpath, subpats, ddpos) => self . check_pat_tuple_struct (
189189 pat,
190190 qpath,
191191 subpats,
192192 ddpos,
193193 expected,
194- PatInfo { binding_mode : def_bm, top_info : ti, decl_ctxt } ,
194+ PatInfo { binding_mode : def_bm, top_info : ti, decl_origin } ,
195195 ) ,
196196 PatKind :: Path ( ref qpath) => {
197197 self . check_pat_path ( pat, qpath, path_res. unwrap ( ) , expected, ti)
@@ -202,14 +202,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
202202 fields,
203203 has_rest_pat,
204204 expected,
205- PatInfo { binding_mode : def_bm, top_info : ti, decl_ctxt } ,
205+ PatInfo { binding_mode : def_bm, top_info : ti, decl_origin } ,
206206 ) ,
207207 PatKind :: Or ( pats) => {
208208 for pat in pats {
209209 self . check_pat (
210210 pat,
211211 expected,
212- PatInfo { binding_mode : def_bm, top_info : ti, decl_ctxt } ,
212+ PatInfo { binding_mode : def_bm, top_info : ti, decl_origin } ,
213213 ) ;
214214 }
215215 expected
@@ -219,28 +219,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
219219 elements,
220220 ddpos,
221221 expected,
222- PatInfo { binding_mode : def_bm, top_info : ti, decl_ctxt } ,
222+ PatInfo { binding_mode : def_bm, top_info : ti, decl_origin } ,
223223 ) ,
224224 PatKind :: Box ( inner) => self . check_pat_box (
225225 pat. span ,
226226 inner,
227227 expected,
228- PatInfo { binding_mode : def_bm, top_info : ti, decl_ctxt } ,
228+ PatInfo { binding_mode : def_bm, top_info : ti, decl_origin } ,
229229 ) ,
230230 PatKind :: Ref ( inner, mutbl) => self . check_pat_ref (
231231 pat,
232232 inner,
233233 mutbl,
234234 expected,
235- PatInfo { binding_mode : def_bm, top_info : ti, decl_ctxt } ,
235+ PatInfo { binding_mode : def_bm, top_info : ti, decl_origin } ,
236236 ) ,
237237 PatKind :: Slice ( before, slice, after) => self . check_pat_slice (
238238 pat. span ,
239239 before,
240240 slice,
241241 after,
242242 expected,
243- PatInfo { binding_mode : def_bm, top_info : ti, decl_ctxt } ,
243+ PatInfo { binding_mode : def_bm, top_info : ti, decl_origin } ,
244244 ) ,
245245 } ;
246246
@@ -622,9 +622,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
622622 var_id : HirId ,
623623 sub : Option < & ' tcx Pat < ' tcx > > ,
624624 expected : Ty < ' tcx > ,
625- pat_info : PatInfo < ' tcx > ,
625+ pat_info : PatInfo < ' tcx , ' _ > ,
626626 ) -> 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;
628628
629629 // Determine the binding mode...
630630 let bm = match ba {
@@ -663,7 +663,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
663663 }
664664
665665 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+ ) ;
667671 }
668672
669673 local_ty
@@ -886,9 +890,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
886890 fields : & ' tcx [ hir:: PatField < ' tcx > ] ,
887891 has_rest_pat : bool ,
888892 expected : Ty < ' tcx > ,
889- pat_info : PatInfo < ' tcx > ,
893+ pat_info : PatInfo < ' tcx , ' _ > ,
890894 ) -> 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;
892896
893897 // Resolve the path and check the definition for errors.
894898 let ( variant, pat_ty) = match self . check_struct_path ( qpath, pat. hir_id ) {
@@ -900,7 +904,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
900904 self . check_pat (
901905 field. pat ,
902906 err,
903- PatInfo { binding_mode : def_bm, top_info : ti, decl_ctxt } ,
907+ PatInfo { binding_mode : def_bm, top_info : ti, decl_origin } ,
904908 ) ;
905909 }
906910 return err;
@@ -917,7 +921,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
917921 variant,
918922 fields,
919923 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 } ,
921925 ) {
922926 pat_ty
923927 } else {
@@ -1083,16 +1087,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10831087 subpats : & ' tcx [ Pat < ' tcx > ] ,
10841088 ddpos : hir:: DotDotPos ,
10851089 expected : Ty < ' tcx > ,
1086- pat_info : PatInfo < ' tcx > ,
1090+ pat_info : PatInfo < ' tcx , ' _ > ,
10871091 ) -> 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;
10891093 let tcx = self . tcx ;
10901094 let on_error = |e| {
10911095 for pat in subpats {
10921096 self . check_pat (
10931097 pat,
10941098 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 } ,
10961100 ) ;
10971101 }
10981102 } ;
@@ -1162,7 +1166,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
11621166 self . check_pat (
11631167 subpat,
11641168 field_ty,
1165- PatInfo { binding_mode : def_bm, top_info : ti, decl_ctxt } ,
1169+ PatInfo { binding_mode : def_bm, top_info : ti, decl_origin } ,
11661170 ) ;
11671171
11681172 self . tcx . check_stability (
@@ -1347,7 +1351,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13471351 elements : & ' tcx [ Pat < ' tcx > ] ,
13481352 ddpos : hir:: DotDotPos ,
13491353 expected : Ty < ' tcx > ,
1350- pat_info : PatInfo < ' tcx > ,
1354+ pat_info : PatInfo < ' tcx , ' _ > ,
13511355 ) -> Ty < ' tcx > {
13521356 let tcx = self . tcx ;
13531357 let mut expected_len = elements. len ( ) ;
@@ -1394,7 +1398,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13941398 variant : & ' tcx ty:: VariantDef ,
13951399 fields : & ' tcx [ hir:: PatField < ' tcx > ] ,
13961400 has_rest_pat : bool ,
1397- pat_info : PatInfo < ' tcx > ,
1401+ pat_info : PatInfo < ' tcx , ' _ > ,
13981402 ) -> bool {
13991403 let tcx = self . tcx ;
14001404
@@ -2004,7 +2008,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
20042008 span : Span ,
20052009 inner : & ' tcx Pat < ' tcx > ,
20062010 expected : Ty < ' tcx > ,
2007- pat_info : PatInfo < ' tcx > ,
2011+ pat_info : PatInfo < ' tcx , ' _ > ,
20082012 ) -> Ty < ' tcx > {
20092013 let tcx = self . tcx ;
20102014 let ( box_ty, inner_ty) = match self . check_dereferenceable ( span, expected, inner) {
@@ -2035,7 +2039,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
20352039 inner : & ' tcx Pat < ' tcx > ,
20362040 mutbl : hir:: Mutability ,
20372041 expected : Ty < ' tcx > ,
2038- pat_info : PatInfo < ' tcx > ,
2042+ pat_info : PatInfo < ' tcx , ' _ > ,
20392043 ) -> Ty < ' tcx > {
20402044 let tcx = self . tcx ;
20412045 let expected = self . shallow_resolve ( expected) ;
@@ -2139,9 +2143,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
21392143 ///
21402144 /// If we're in an irrefutable pattern we prefer the array impl candidate given that
21412145 /// 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 { .. } )
21452150 } else {
21462151 false
21472152 }
@@ -2164,11 +2169,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
21642169 slice : Option < & ' tcx Pat < ' tcx > > ,
21652170 after : & ' tcx [ Pat < ' tcx > ] ,
21662171 expected : Ty < ' tcx > ,
2167- pat_info : PatInfo < ' tcx > ,
2172+ pat_info : PatInfo < ' tcx , ' _ > ,
21682173 ) -> Ty < ' tcx > {
21692174 // If the pattern is irrefutable and `expected` is an infer ty, we try to equate it
21702175 // 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 ( ) {
21722177 if let Some ( resolved_arr_ty) =
21732178 self . try_resolve_slice_ty_to_array_ty ( before, slice, span)
21742179 {
0 commit comments