@@ -2024,6 +2024,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
20242024 Ty :: new_ref ( self . tcx , region, mt)
20252025 }
20262026
2027+ fn try_resolve_slice_ty_to_array_ty (
2028+ & self ,
2029+ before : & ' tcx [ Pat < ' tcx > ] ,
2030+ slice : Option < & ' tcx Pat < ' tcx > > ,
2031+ span : Span ,
2032+ ) -> Option < Ty < ' tcx > > {
2033+ if !slice. is_none ( ) {
2034+ return None ;
2035+ }
2036+
2037+ let tcx = self . tcx ;
2038+ let len = before. len ( ) ;
2039+ let ty_var_origin =
2040+ TypeVariableOrigin { kind : TypeVariableOriginKind :: TypeInference , span } ;
2041+ let inner_ty = self . next_ty_var ( ty_var_origin) ;
2042+
2043+ Some ( tcx. mk_array ( inner_ty, len. try_into ( ) . unwrap ( ) ) )
2044+ }
2045+
20272046 /// Type check a slice pattern.
20282047 ///
20292048 /// Syntactically, these look like `[pat_0, ..., pat_n]`.
@@ -2044,6 +2063,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
20442063 def_bm : BindingMode ,
20452064 ti : TopInfo < ' tcx > ,
20462065 ) -> Ty < ' tcx > {
2066+ // If `expected` is an infer ty, we try to equate it to an array if the given pattern
2067+ // allows it. See issue #76342
2068+ if let Some ( resolved_arr_ty) = self . try_resolve_slice_ty_to_array_ty ( before, slice, span) && expected. is_ty_var ( ) {
2069+ debug ! ( ?resolved_arr_ty) ;
2070+ self . demand_eqtype ( span, expected, resolved_arr_ty) ;
2071+ }
2072+
20472073 let expected = self . structurally_resolve_type ( span, expected) ;
20482074 let ( element_ty, opt_slice_ty, inferred) = match * expected. kind ( ) {
20492075 // An array, so we might have something like `let [a, b, c] = [0, 1, 2];`.
0 commit comments