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.rs105
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));
-}