Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/infer/closure.rs')
| -rw-r--r-- | crates/hir-ty/src/infer/closure.rs | 105 |
1 files changed, 31 insertions, 74 deletions
diff --git a/crates/hir-ty/src/infer/closure.rs b/crates/hir-ty/src/infer/closure.rs index 662f2e5fa1..754ac88bb5 100644 --- a/crates/hir-ty/src/infer/closure.rs +++ b/crates/hir-ty/src/infer/closure.rs @@ -9,10 +9,7 @@ use chalk_ir::{ }; use hir_def::{ data::adt::VariantData, - hir::{ - Array, BinaryOp, BindingAnnotation, BindingId, CaptureBy, Expr, ExprId, Pat, PatId, - Statement, UnaryOp, - }, + hir::{Array, BinaryOp, BindingId, CaptureBy, Expr, ExprId, Pat, PatId, Statement, UnaryOp}, lang_item::LangItem, resolver::{resolver_for_expr, ResolveValueResult, ValueNs}, DefWithBodyId, FieldId, HasModule, VariantId, @@ -28,9 +25,9 @@ use crate::{ mir::{BorrowKind, MirSpan, ProjectionElem}, static_lifetime, to_chalk_trait_id, traits::FnTrait, - utils::{self, generics, pattern_matching_dereference_count, Generics}, - Adjust, Adjustment, Binders, ChalkTraitId, ClosureId, ConstValue, DynTy, FnPointer, FnSig, - Interner, Substitution, Ty, TyExt, + utils::{self, generics, Generics}, + Adjust, Adjustment, Binders, BindingMode, ChalkTraitId, ClosureId, ConstValue, DynTy, + FnPointer, FnSig, Interner, Substitution, Ty, TyExt, }; use super::{Expectation, InferenceContext}; @@ -488,13 +485,7 @@ impl InferenceContext<'_> { if let Some(initializer) = initializer { self.walk_expr(*initializer); if let Some(place) = self.place_of_expr(*initializer) { - let ty = self.expr_ty(*initializer); - self.consume_with_pat( - place, - ty, - BindingAnnotation::Unannotated, - *pat, - ); + self.consume_with_pat(place, *pat); } } } @@ -799,41 +790,37 @@ impl InferenceContext<'_> { } } - fn consume_with_pat( - &mut self, - mut place: HirPlace, - mut ty: Ty, - mut bm: BindingAnnotation, - pat: PatId, - ) { + fn consume_with_pat(&mut self, mut place: HirPlace, pat: PatId) { + let cnt = self.result.pat_adjustments.get(&pat).map(|x| x.len()).unwrap_or_default(); + place.projections = place + .projections + .iter() + .cloned() + .chain((0..cnt).map(|_| ProjectionElem::Deref)) + .collect::<Vec<_>>() + .into(); match &self.body[pat] { Pat::Missing | Pat::Wild => (), Pat::Tuple { args, ellipsis } => { - pattern_matching_dereference(&mut ty, &mut bm, &mut place); let (al, ar) = args.split_at(ellipsis.unwrap_or(args.len())); - let subst = match ty.kind(Interner) { - TyKind::Tuple(_, s) => s, + let field_count = match self.result[pat].kind(Interner) { + TyKind::Tuple(_, s) => s.len(Interner), _ => return, }; - let fields = subst.iter(Interner).map(|x| x.assert_ty_ref(Interner)).enumerate(); + let fields = 0..field_count; let it = al.iter().zip(fields.clone()).chain(ar.iter().rev().zip(fields.rev())); - for (arg, (i, ty)) in it { + for (arg, i) in it { let mut p = place.clone(); p.projections.push(ProjectionElem::TupleOrClosureField(i)); - self.consume_with_pat(p, ty.clone(), bm, *arg); + self.consume_with_pat(p, *arg); } } Pat::Or(pats) => { for pat in pats.iter() { - self.consume_with_pat(place.clone(), ty.clone(), bm, *pat); + self.consume_with_pat(place.clone(), *pat); } } Pat::Record { args, .. } => { - pattern_matching_dereference(&mut ty, &mut bm, &mut place); - let subst = match ty.kind(Interner) { - TyKind::Adt(_, s) => s, - _ => return, - }; let Some(variant) = self.result.variant_resolution_for_pat(pat) else { return; }; @@ -843,7 +830,6 @@ impl InferenceContext<'_> { } VariantId::StructId(s) => { let vd = &*self.db.struct_data(s).variant_data; - let field_types = self.db.field_types(variant); for field_pat in args.iter() { let arg = field_pat.pat; let Some(local_id) = vd.field(&field_pat.name) else { @@ -854,12 +840,7 @@ impl InferenceContext<'_> { parent: variant.into(), local_id, })); - self.consume_with_pat( - p, - field_types[local_id].clone().substitute(Interner, subst), - bm, - arg, - ); + self.consume_with_pat(p, arg); } } } @@ -870,26 +851,20 @@ impl InferenceContext<'_> { | Pat::Path(_) | Pat::Lit(_) => self.consume_place(place, pat.into()), Pat::Bind { id, subpat: _ } => { - let mode = self.body.bindings[*id].mode; - if matches!(mode, BindingAnnotation::Ref | BindingAnnotation::RefMut) { - bm = mode; - } - let capture_kind = match bm { - BindingAnnotation::Unannotated | BindingAnnotation::Mutable => { + let mode = self.result.binding_modes[*id]; + let capture_kind = match mode { + BindingMode::Move => { self.consume_place(place, pat.into()); return; } - BindingAnnotation::Ref => BorrowKind::Shared, - BindingAnnotation::RefMut => BorrowKind::Mut { allow_two_phase_borrow: false }, + BindingMode::Ref(Mutability::Not) => BorrowKind::Shared, + BindingMode::Ref(Mutability::Mut) => { + BorrowKind::Mut { allow_two_phase_borrow: false } + } }; self.add_capture(place, CaptureKind::ByRef(capture_kind), pat.into()); } Pat::TupleStruct { path: _, args, ellipsis } => { - pattern_matching_dereference(&mut ty, &mut bm, &mut place); - let subst = match ty.kind(Interner) { - TyKind::Adt(_, s) => s, - _ => return, - }; let Some(variant) = self.result.variant_resolution_for_pat(pat) else { return; }; @@ -903,29 +878,20 @@ impl InferenceContext<'_> { let fields = vd.fields().iter(); let it = al.iter().zip(fields.clone()).chain(ar.iter().rev().zip(fields.rev())); - let field_types = self.db.field_types(variant); for (arg, (i, _)) in it { let mut p = place.clone(); p.projections.push(ProjectionElem::Field(FieldId { parent: variant.into(), local_id: i, })); - self.consume_with_pat( - p, - field_types[i].clone().substitute(Interner, subst), - bm, - *arg, - ); + self.consume_with_pat(p, *arg); } } } } Pat::Ref { pat, mutability: _ } => { - if let Some((inner, _, _)) = ty.as_reference() { - ty = inner.clone(); - place.projections.push(ProjectionElem::Deref); - self.consume_with_pat(place, ty, bm, *pat) - } + place.projections.push(ProjectionElem::Deref); + self.consume_with_pat(place, *pat) } Pat::Box { .. } => (), // not supported } @@ -1054,12 +1020,3 @@ fn apply_adjusts_to_place(mut r: HirPlace, adjustments: &[Adjustment]) -> Option } Some(r) } - -fn pattern_matching_dereference( - cond_ty: &mut Ty, - binding_mode: &mut BindingAnnotation, - cond_place: &mut HirPlace, -) { - let cnt = pattern_matching_dereference_count(cond_ty, binding_mode); - cond_place.projections.extend((0..cnt).map(|_| ProjectionElem::Deref)); -} |