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.rs33
1 files changed, 30 insertions, 3 deletions
diff --git a/crates/hir-ty/src/infer/closure.rs b/crates/hir-ty/src/infer/closure.rs
index 28cb301f3e..6927d89d63 100644
--- a/crates/hir-ty/src/infer/closure.rs
+++ b/crates/hir-ty/src/infer/closure.rs
@@ -190,6 +190,16 @@ impl InferenceContext<'_> {
}
return Some(place);
}
+ Expr::UnaryOp { expr, op: UnaryOp::Deref } => {
+ if matches!(
+ self.expr_ty_after_adjustments(*expr).kind(Interner),
+ TyKind::Ref(..) | TyKind::Raw(..)
+ ) {
+ let mut place = self.place_of_expr(*expr)?;
+ place.projections.push(ProjectionElem::Deref);
+ return Some(place);
+ }
+ }
_ => (),
}
None
@@ -371,7 +381,12 @@ impl InferenceContext<'_> {
}
Expr::Field { expr, name: _ } => self.select_from_expr(*expr),
Expr::UnaryOp { expr, op: UnaryOp::Deref } => {
- if let Some((f, _)) = self.result.method_resolution(tgt_expr) {
+ if matches!(
+ self.expr_ty_after_adjustments(*expr).kind(Interner),
+ TyKind::Ref(..) | TyKind::Raw(..)
+ ) {
+ self.select_from_expr(*expr);
+ } else if let Some((f, _)) = self.result.method_resolution(tgt_expr) {
let mutability = 'b: {
if let Some(deref_trait) =
self.resolve_lang_item(LangItem::DerefMut).and_then(|x| x.as_trait())
@@ -461,10 +476,20 @@ impl InferenceContext<'_> {
}
}
- fn expr_ty(&mut self, expr: ExprId) -> Ty {
+ fn expr_ty(&self, expr: ExprId) -> Ty {
self.result[expr].clone()
}
+ fn expr_ty_after_adjustments(&self, e: ExprId) -> Ty {
+ let mut ty = None;
+ if let Some(x) = self.result.expr_adjustments.get(&e) {
+ if let Some(x) = x.last() {
+ ty = Some(x.target.clone());
+ }
+ }
+ ty.unwrap_or_else(|| self.expr_ty(e))
+ }
+
fn is_upvar(&self, place: &HirPlace) -> bool {
let b = &self.body[place.local];
if let Some(c) = self.current_closure {
@@ -701,7 +726,9 @@ impl InferenceContext<'_> {
};
self.consume_expr(*body);
for item in &self.current_captures {
- if matches!(item.kind, CaptureKind::ByRef(BorrowKind::Mut { .. })) {
+ if matches!(item.kind, CaptureKind::ByRef(BorrowKind::Mut { .. }))
+ && !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.
self.result.mutated_bindings_in_closure.insert(item.place.local);