Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/infer/mutability.rs')
-rw-r--r--crates/hir-ty/src/infer/mutability.rs26
1 files changed, 20 insertions, 6 deletions
diff --git a/crates/hir-ty/src/infer/mutability.rs b/crates/hir-ty/src/infer/mutability.rs
index 8e52725e53..6a0daee6ea 100644
--- a/crates/hir-ty/src/infer/mutability.rs
+++ b/crates/hir-ty/src/infer/mutability.rs
@@ -12,12 +12,11 @@ use hir_expand::name::Name;
use intern::sym;
use crate::{
- infer::Expectation, lower::lower_to_chalk_mutability, Adjust, Adjustment, AutoBorrow, Interner,
- OverloadedDeref, TyBuilder, TyKind,
+ infer::{expr::ExprIsRead, Expectation, InferenceContext},
+ lower::lower_to_chalk_mutability,
+ Adjust, Adjustment, AutoBorrow, Interner, OverloadedDeref, TyBuilder, TyKind,
};
-use super::InferenceContext;
-
impl InferenceContext<'_> {
pub(crate) fn infer_mut_body(&mut self) {
self.infer_mut_expr(self.body.body_expr, Mutability::Not);
@@ -164,7 +163,11 @@ impl InferenceContext<'_> {
if let Some(ty) = self.result.type_of_expr.get(index) {
ty.clone()
} else {
- self.infer_expr(index, &Expectation::none())
+ self.infer_expr(
+ index,
+ &Expectation::none(),
+ ExprIsRead::Yes,
+ )
};
let trait_ref = TyBuilder::trait_ref(self.db, index_trait)
.push(base_ty)
@@ -180,6 +183,7 @@ impl InferenceContext<'_> {
self.infer_mut_expr(index, Mutability::Not);
}
Expr::UnaryOp { expr, op: UnaryOp::Deref } => {
+ let mut mutability = mutability;
if let Some((f, _)) = self.result.method_resolutions.get_mut(&tgt_expr) {
if mutability == Mutability::Mut {
if let Some(deref_trait) = self
@@ -187,7 +191,17 @@ impl InferenceContext<'_> {
.lang_item(self.table.trait_env.krate, LangItem::DerefMut)
.and_then(|l| l.as_trait())
{
- if let Some(deref_fn) = self
+ let ty = self.result.type_of_expr.get(*expr);
+ let is_mut_ptr = ty.is_some_and(|ty| {
+ let ty = self.table.resolve_ty_shallow(ty);
+ matches!(
+ ty.kind(Interner),
+ chalk_ir::TyKind::Raw(Mutability::Mut, _)
+ )
+ });
+ if is_mut_ptr {
+ mutability = Mutability::Not;
+ } else if let Some(deref_fn) = self
.db
.trait_data(deref_trait)
.method_by_name(&Name::new_symbol_root(sym::deref_mut.clone()))