@@ -19,8 +19,8 @@ use crate::{
1919 } ,
2020 lower:: lower_to_chalk_mutability,
2121 primitive:: UintTy ,
22- static_lifetime, InferenceDiagnostic , Interner , Mutability , Scalar , Substitution , Ty ,
23- TyBuilder , TyExt , TyKind ,
22+ static_lifetime, DeclContext , DeclOrigin , InferenceDiagnostic , Interner , Mutability , Scalar ,
23+ Substitution , Ty , TyBuilder , TyExt , TyKind ,
2424} ;
2525
2626impl InferenceContext < ' _ > {
@@ -35,6 +35,7 @@ impl InferenceContext<'_> {
3535 id : PatId ,
3636 ellipsis : Option < u32 > ,
3737 subs : & [ PatId ] ,
38+ decl : Option < DeclContext > ,
3839 ) -> Ty {
3940 let ( ty, def) = self . resolve_variant ( id. into ( ) , path, true ) ;
4041 let var_data = def. map ( |it| it. variant_data ( self . db . upcast ( ) ) ) ;
@@ -93,13 +94,13 @@ impl InferenceContext<'_> {
9394 }
9495 } ;
9596
96- self . infer_pat ( subpat, & expected_ty, default_bm) ;
97+ self . infer_pat ( subpat, & expected_ty, default_bm, decl ) ;
9798 }
9899 }
99100 None => {
100101 let err_ty = self . err_ty ( ) ;
101102 for & inner in subs {
102- self . infer_pat ( inner, & err_ty, default_bm) ;
103+ self . infer_pat ( inner, & err_ty, default_bm, decl ) ;
103104 }
104105 }
105106 }
@@ -115,6 +116,7 @@ impl InferenceContext<'_> {
115116 default_bm : BindingMode ,
116117 id : PatId ,
117118 subs : impl ExactSizeIterator < Item = ( Name , PatId ) > ,
119+ decl : Option < DeclContext > ,
118120 ) -> Ty {
119121 let ( ty, def) = self . resolve_variant ( id. into ( ) , path, false ) ;
120122 if let Some ( variant) = def {
@@ -163,13 +165,13 @@ impl InferenceContext<'_> {
163165 }
164166 } ;
165167
166- self . infer_pat ( inner, & expected_ty, default_bm) ;
168+ self . infer_pat ( inner, & expected_ty, default_bm, decl ) ;
167169 }
168170 }
169171 None => {
170172 let err_ty = self . err_ty ( ) ;
171173 for ( _, inner) in subs {
172- self . infer_pat ( inner, & err_ty, default_bm) ;
174+ self . infer_pat ( inner, & err_ty, default_bm, decl ) ;
173175 }
174176 }
175177 }
@@ -186,6 +188,7 @@ impl InferenceContext<'_> {
186188 default_bm : BindingMode ,
187189 ellipsis : Option < u32 > ,
188190 subs : & [ PatId ] ,
191+ decl : Option < DeclContext > ,
189192 ) -> Ty {
190193 let expected = self . resolve_ty_shallow ( expected) ;
191194 let expectations = match expected. as_tuple ( ) {
@@ -210,12 +213,12 @@ impl InferenceContext<'_> {
210213
211214 // Process pre
212215 for ( ty, pat) in inner_tys. iter_mut ( ) . zip ( pre) {
213- * ty = self . infer_pat ( * pat, ty, default_bm) ;
216+ * ty = self . infer_pat ( * pat, ty, default_bm, decl ) ;
214217 }
215218
216219 // Process post
217220 for ( ty, pat) in inner_tys. iter_mut ( ) . skip ( pre. len ( ) + n_uncovered_patterns) . zip ( post) {
218- * ty = self . infer_pat ( * pat, ty, default_bm) ;
221+ * ty = self . infer_pat ( * pat, ty, default_bm, decl ) ;
219222 }
220223
221224 TyKind :: Tuple ( inner_tys. len ( ) , Substitution :: from_iter ( Interner , inner_tys) )
@@ -224,11 +227,17 @@ impl InferenceContext<'_> {
224227
225228 /// The resolver needs to be updated to the surrounding expression when inside assignment
226229 /// (because there, `Pat::Path` can refer to a variable).
227- pub ( super ) fn infer_top_pat ( & mut self , pat : PatId , expected : & Ty ) {
228- self . infer_pat ( pat, expected, BindingMode :: default ( ) ) ;
230+ pub ( super ) fn infer_top_pat ( & mut self , pat : PatId , expected : & Ty , decl : Option < DeclContext > ) {
231+ self . infer_pat ( pat, expected, BindingMode :: default ( ) , decl ) ;
229232 }
230233
231- fn infer_pat ( & mut self , pat : PatId , expected : & Ty , mut default_bm : BindingMode ) -> Ty {
234+ fn infer_pat (
235+ & mut self ,
236+ pat : PatId ,
237+ expected : & Ty ,
238+ mut default_bm : BindingMode ,
239+ decl : Option < DeclContext > ,
240+ ) -> Ty {
232241 let mut expected = self . resolve_ty_shallow ( expected) ;
233242
234243 if matches ! ( & self . body[ pat] , Pat :: Ref { .. } ) || self . inside_assignment {
@@ -262,11 +271,11 @@ impl InferenceContext<'_> {
262271
263272 let ty = match & self . body [ pat] {
264273 Pat :: Tuple { args, ellipsis } => {
265- self . infer_tuple_pat_like ( & expected, default_bm, * ellipsis, args)
274+ self . infer_tuple_pat_like ( & expected, default_bm, * ellipsis, args, decl )
266275 }
267276 Pat :: Or ( pats) => {
268277 for pat in pats. iter ( ) {
269- self . infer_pat ( * pat, & expected, default_bm) ;
278+ self . infer_pat ( * pat, & expected, default_bm, decl ) ;
270279 }
271280 expected. clone ( )
272281 }
@@ -275,6 +284,7 @@ impl InferenceContext<'_> {
275284 lower_to_chalk_mutability ( mutability) ,
276285 & expected,
277286 default_bm,
287+ decl,
278288 ) ,
279289 Pat :: TupleStruct { path : p, args : subpats, ellipsis } => self
280290 . infer_tuple_struct_pat_like (
@@ -284,10 +294,11 @@ impl InferenceContext<'_> {
284294 pat,
285295 * ellipsis,
286296 subpats,
297+ decl,
287298 ) ,
288299 Pat :: Record { path : p, args : fields, ellipsis : _ } => {
289300 let subs = fields. iter ( ) . map ( |f| ( f. name . clone ( ) , f. pat ) ) ;
290- self . infer_record_pat_like ( p. as_deref ( ) , & expected, default_bm, pat, subs)
301+ self . infer_record_pat_like ( p. as_deref ( ) , & expected, default_bm, pat, subs, decl )
291302 }
292303 Pat :: Path ( path) => {
293304 let ty = self . infer_path ( path, pat. into ( ) ) . unwrap_or_else ( || self . err_ty ( ) ) ;
@@ -320,10 +331,10 @@ impl InferenceContext<'_> {
320331 }
321332 }
322333 Pat :: Bind { id, subpat } => {
323- return self . infer_bind_pat ( pat, * id, default_bm, * subpat, & expected) ;
334+ return self . infer_bind_pat ( pat, * id, default_bm, * subpat, & expected, decl ) ;
324335 }
325336 Pat :: Slice { prefix, slice, suffix } => {
326- self . infer_slice_pat ( & expected, prefix, slice, suffix, default_bm)
337+ self . infer_slice_pat ( & expected, prefix, slice, suffix, default_bm, decl )
327338 }
328339 Pat :: Wild => expected. clone ( ) ,
329340 Pat :: Range { .. } => {
@@ -346,7 +357,7 @@ impl InferenceContext<'_> {
346357 _ => ( self . result . standard_types . unknown . clone ( ) , None ) ,
347358 } ;
348359
349- let inner_ty = self . infer_pat ( * inner, & inner_ty, default_bm) ;
360+ let inner_ty = self . infer_pat ( * inner, & inner_ty, default_bm, decl ) ;
350361 let mut b = TyBuilder :: adt ( self . db , box_adt) . push ( inner_ty) ;
351362
352363 if let Some ( alloc_ty) = alloc_ty {
@@ -421,6 +432,7 @@ impl InferenceContext<'_> {
421432 mutability : Mutability ,
422433 expected : & Ty ,
423434 default_bm : BindingMode ,
435+ decl : Option < DeclContext > ,
424436 ) -> Ty {
425437 let ( expectation_type, expectation_lt) = match expected. as_reference ( ) {
426438 Some ( ( inner_ty, lifetime, _exp_mut) ) => ( inner_ty. clone ( ) , lifetime. clone ( ) ) ,
@@ -434,7 +446,7 @@ impl InferenceContext<'_> {
434446 ( inner_ty, inner_lt)
435447 }
436448 } ;
437- let subty = self . infer_pat ( inner_pat, & expectation_type, default_bm) ;
449+ let subty = self . infer_pat ( inner_pat, & expectation_type, default_bm, decl ) ;
438450 TyKind :: Ref ( mutability, expectation_lt, subty) . intern ( Interner )
439451 }
440452
@@ -445,6 +457,7 @@ impl InferenceContext<'_> {
445457 default_bm : BindingMode ,
446458 subpat : Option < PatId > ,
447459 expected : & Ty ,
460+ decl : Option < DeclContext > ,
448461 ) -> Ty {
449462 let Binding { mode, .. } = self . body . bindings [ binding] ;
450463 let mode = if mode == BindingAnnotation :: Unannotated {
@@ -455,7 +468,7 @@ impl InferenceContext<'_> {
455468 self . result . binding_modes . insert ( pat, mode) ;
456469
457470 let inner_ty = match subpat {
458- Some ( subpat) => self . infer_pat ( subpat, expected, default_bm) ,
471+ Some ( subpat) => self . infer_pat ( subpat, expected, default_bm, decl ) ,
459472 None => expected. clone ( ) ,
460473 } ;
461474 let inner_ty = self . insert_type_vars_shallow ( inner_ty) ;
@@ -479,12 +492,13 @@ impl InferenceContext<'_> {
479492 slice : & Option < PatId > ,
480493 suffix : & [ PatId ] ,
481494 default_bm : BindingMode ,
495+ decl : Option < DeclContext > ,
482496 ) -> Ty {
483497 let expected = self . resolve_ty_shallow ( expected) ;
484498
485499 // If `expected` is an infer ty, we try to equate it to an array if the given pattern
486500 // allows it. See issue #16609
487- if expected. is_ty_var ( ) {
501+ if self . decl_allows_array_type_infer ( decl ) && expected. is_ty_var ( ) {
488502 if let Some ( resolved_array_ty) =
489503 self . try_resolve_slice_ty_to_array_ty ( prefix, suffix, slice)
490504 {
@@ -499,7 +513,7 @@ impl InferenceContext<'_> {
499513 } ;
500514
501515 for & pat_id in prefix. iter ( ) . chain ( suffix. iter ( ) ) {
502- self . infer_pat ( pat_id, & elem_ty, default_bm) ;
516+ self . infer_pat ( pat_id, & elem_ty, default_bm, decl ) ;
503517 }
504518
505519 if let & Some ( slice_pat_id) = slice {
@@ -513,7 +527,7 @@ impl InferenceContext<'_> {
513527 _ => TyKind :: Slice ( elem_ty. clone ( ) ) ,
514528 }
515529 . intern ( Interner ) ;
516- self . infer_pat ( slice_pat_id, & rest_pat_ty, default_bm) ;
530+ self . infer_pat ( slice_pat_id, & rest_pat_ty, default_bm, decl ) ;
517531 }
518532
519533 match expected. kind ( Interner ) {
@@ -586,6 +600,44 @@ impl InferenceContext<'_> {
586600 let array_ty = TyKind :: Array ( elem_ty. clone ( ) , size) . intern ( Interner ) ;
587601 Some ( array_ty)
588602 }
603+
604+ /// Determines whether we can infer the expected type in the slice pattern to be of type array.
605+ /// This is only possible if we're in an irrefutable pattern. If we were to allow this in refutable
606+ /// patterns we wouldn't e.g. report ambiguity in the following situation:
607+ ///
608+ /// ```ignore(rust)
609+ /// struct Zeroes;
610+ /// const ARR: [usize; 2] = [0; 2];
611+ /// const ARR2: [usize; 2] = [2; 2];
612+ ///
613+ /// impl Into<&'static [usize; 2]> for Zeroes {
614+ /// fn into(self) -> &'static [usize; 2] {
615+ /// &ARR
616+ /// }
617+ /// }
618+ ///
619+ /// impl Into<&'static [usize]> for Zeroes {
620+ /// fn into(self) -> &'static [usize] {
621+ /// &ARR2
622+ /// }
623+ /// }
624+ ///
625+ /// fn main() {
626+ /// let &[a, b]: &[usize] = Zeroes.into() else {
627+ /// ..
628+ /// };
629+ /// }
630+ /// ```
631+ ///
632+ /// If we're in an irrefutable pattern we prefer the array impl candidate given that
633+ /// the slice impl candidate would be be rejected anyway (if no ambiguity existed).
634+ fn decl_allows_array_type_infer ( & self , decl_ctxt : Option < DeclContext > ) -> bool {
635+ if let Some ( decl_ctxt) = decl_ctxt {
636+ !decl_ctxt. has_else && matches ! ( decl_ctxt. origin, DeclOrigin :: LocalDecl )
637+ } else {
638+ false
639+ }
640+ }
589641}
590642
591643pub ( super ) fn contains_explicit_ref_binding ( body : & Body , pat_id : PatId ) -> bool {
0 commit comments