diff options
| author | b-naber <b_naber@gmx.de> | 2023-06-21 17:13:06 +0000 |
|---|---|---|
| committer | b-naber <b_naber@gmx.de> | 2023-07-17 22:00:43 +0000 |
| commit | 2827aa975257d03f21c75fa27a594079a9da31ba (patch) | |
| tree | 88d6c2fa9134252e907b57579eab2681b19f83c9 | |
| parent | 1787f312907eee9a4a9ac010985d725ad9a03ab6 (diff) | |
try to infer array type from slice pattern
| -rw-r--r-- | compiler/rustc_hir_typeck/src/pat.rs | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 8bf95d4bf9a..4785564d850 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -2024,6 +2024,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Ty::new_ref(self.tcx, region, mt) } + fn try_resolve_slice_ty_to_array_ty( + &self, + before: &'tcx [Pat<'tcx>], + slice: Option<&'tcx Pat<'tcx>>, + span: Span, + ) -> Option<Ty<'tcx>> { + if !slice.is_none() { + return None; + } + + let tcx = self.tcx; + let len = before.len(); + let ty_var_origin = + TypeVariableOrigin { kind: TypeVariableOriginKind::TypeInference, span }; + let inner_ty = self.next_ty_var(ty_var_origin); + + Some(tcx.mk_array(inner_ty, len.try_into().unwrap())) + } + /// Type check a slice pattern. /// /// Syntactically, these look like `[pat_0, ..., pat_n]`. @@ -2044,6 +2063,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { def_bm: BindingMode, ti: TopInfo<'tcx>, ) -> Ty<'tcx> { + // If `expected` is an infer ty, we try to equate it to an array if the given pattern + // allows it. See issue #76342 + if let Some(resolved_arr_ty) = self.try_resolve_slice_ty_to_array_ty(before, slice, span) && expected.is_ty_var() { + debug!(?resolved_arr_ty); + self.demand_eqtype(span, expected, resolved_arr_ty); + } + let expected = self.structurally_resolve_type(span, expected); let (element_ty, opt_slice_ty, inferred) = match *expected.kind() { // An array, so we might have something like `let [a, b, c] = [0, 1, 2];`. |
