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.rs34
1 files changed, 19 insertions, 15 deletions
diff --git a/crates/hir-ty/src/infer/closure.rs b/crates/hir-ty/src/infer/closure.rs
index 22a70f951e..000248c2ce 100644
--- a/crates/hir-ty/src/infer/closure.rs
+++ b/crates/hir-ty/src/infer/closure.rs
@@ -23,7 +23,7 @@ use stdx::never;
use crate::{
db::{HirDatabase, InternedClosure},
from_placeholder_idx, make_binders,
- mir::{BorrowKind, MirSpan, ProjectionElem},
+ mir::{BorrowKind, MirSpan, MutBorrowKind, ProjectionElem},
static_lifetime, to_chalk_trait_id,
traits::FnTrait,
utils::{self, generics, Generics},
@@ -142,9 +142,13 @@ impl HirPlace {
mut current_capture: CaptureKind,
len: usize,
) -> CaptureKind {
- if let CaptureKind::ByRef(BorrowKind::Mut { .. }) = current_capture {
+ if let CaptureKind::ByRef(BorrowKind::Mut {
+ kind: MutBorrowKind::Default | MutBorrowKind::TwoPhasedBorrow,
+ }) = current_capture
+ {
if self.projections[len..].iter().any(|it| *it == ProjectionElem::Deref) {
- current_capture = CaptureKind::ByRef(BorrowKind::Unique);
+ current_capture =
+ CaptureKind::ByRef(BorrowKind::Mut { kind: MutBorrowKind::ClosureCapture });
}
}
current_capture
@@ -377,7 +381,7 @@ impl InferenceContext<'_> {
if let Some(place) = self.place_of_expr(expr) {
self.add_capture(
place,
- CaptureKind::ByRef(BorrowKind::Mut { allow_two_phase_borrow: false }),
+ CaptureKind::ByRef(BorrowKind::Mut { kind: MutBorrowKind::Default }),
expr.into(),
);
}
@@ -426,9 +430,7 @@ impl InferenceContext<'_> {
fn ref_capture_with_adjusts(&mut self, m: Mutability, tgt_expr: ExprId, rest: &[Adjustment]) {
let capture_kind = match m {
- Mutability::Mut => {
- CaptureKind::ByRef(BorrowKind::Mut { allow_two_phase_borrow: false })
- }
+ Mutability::Mut => CaptureKind::ByRef(BorrowKind::Mut { kind: MutBorrowKind::Default }),
Mutability::Not => CaptureKind::ByRef(BorrowKind::Shared),
};
if let Some(place) = self.place_of_expr_without_adjust(tgt_expr) {
@@ -648,7 +650,7 @@ impl InferenceContext<'_> {
self.walk_pat_inner(
pat,
&mut update_result,
- BorrowKind::Mut { allow_two_phase_borrow: false },
+ BorrowKind::Mut { kind: MutBorrowKind::Default },
);
}
@@ -699,7 +701,7 @@ impl InferenceContext<'_> {
},
}
if self.result.pat_adjustments.get(&p).map_or(false, |it| !it.is_empty()) {
- for_mut = BorrowKind::Unique;
+ for_mut = BorrowKind::Mut { kind: MutBorrowKind::ClosureCapture };
}
self.body.walk_pats_shallow(p, |p| self.walk_pat_inner(p, update_result, for_mut));
}
@@ -880,7 +882,7 @@ impl InferenceContext<'_> {
}
BindingMode::Ref(Mutability::Not) => BorrowKind::Shared,
BindingMode::Ref(Mutability::Mut) => {
- BorrowKind::Mut { allow_two_phase_borrow: false }
+ BorrowKind::Mut { kind: MutBorrowKind::Default }
}
};
self.add_capture(place, CaptureKind::ByRef(capture_kind), pat.into());
@@ -930,9 +932,7 @@ impl InferenceContext<'_> {
r = cmp::min(
r,
match &it.kind {
- CaptureKind::ByRef(BorrowKind::Unique | BorrowKind::Mut { .. }) => {
- FnTrait::FnMut
- }
+ CaptureKind::ByRef(BorrowKind::Mut { .. }) => FnTrait::FnMut,
CaptureKind::ByRef(BorrowKind::Shallow | BorrowKind::Shared) => FnTrait::Fn,
CaptureKind::ByValue => FnTrait::FnOnce,
},
@@ -949,8 +949,12 @@ impl InferenceContext<'_> {
};
self.consume_expr(*body);
for item in &self.current_captures {
- if matches!(item.kind, CaptureKind::ByRef(BorrowKind::Mut { .. }))
- && !item.place.projections.contains(&ProjectionElem::Deref)
+ if matches!(
+ item.kind,
+ CaptureKind::ByRef(BorrowKind::Mut {
+ kind: MutBorrowKind::Default | MutBorrowKind::TwoPhasedBorrow
+ })
+ ) && !item.place.projections.contains(&ProjectionElem::Deref)
{
// FIXME: remove the `mutated_bindings_in_closure` completely and add proper fake reads in
// MIR. I didn't do that due duplicate diagnostics.