Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 0f4e313

Browse files
committed
Fix goto deref_mut
1 parent d1bdebf commit 0f4e313

File tree

1 file changed

+26
-6
lines changed

1 file changed

+26
-6
lines changed

crates/hir/src/source_analyzer.rs

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ use hir_ty::{
4242
use itertools::Itertools;
4343
use smallvec::SmallVec;
4444
use syntax::{
45-
ast::{self, AstNode},
45+
ast::{self, AstNode, BinExpr, Expr, IdentPat, PathExpr},
4646
SyntaxKind, SyntaxNode, TextRange, TextSize,
4747
};
4848
use triomphe::Arc;
@@ -377,14 +377,34 @@ impl SourceAnalyzer {
377377
db: &dyn HirDatabase,
378378
prefix_expr: &ast::PrefixExpr,
379379
) -> Option<FunctionId> {
380-
let (lang_item, fn_name) = match prefix_expr.op_kind()? {
381-
ast::UnaryOp::Deref => (LangItem::Deref, name![deref]),
382-
ast::UnaryOp::Not => (LangItem::Not, name![not]),
383-
ast::UnaryOp::Neg => (LangItem::Neg, name![neg]),
380+
let (op_trait, op_fn) = match prefix_expr.op_kind()? {
381+
ast::UnaryOp::Deref => {
382+
// This can be either `Deref::deref` or `DerefMut::deref_mut`.
383+
// Since deref kind is inferenced and stored in `InferenceResult.method_resolution`,
384+
// use that result to find out which one it is.
385+
let (deref_trait, deref) =
386+
self.lang_trait_fn(db, LangItem::Deref, &name![deref])?;
387+
self.infer
388+
.as_ref()
389+
.and_then(|infer| {
390+
let expr = self.expr_id(db, &prefix_expr.clone().into())?;
391+
let (func, _) = infer.method_resolution(expr)?;
392+
let (deref_mut_trait, deref_mut) =
393+
self.lang_trait_fn(db, LangItem::DerefMut, &name![deref_mut])?;
394+
if func == deref_mut {
395+
Some((deref_mut_trait, deref_mut))
396+
} else {
397+
None
398+
}
399+
})
400+
.unwrap_or((deref_trait, deref))
401+
}
402+
ast::UnaryOp::Not => self.lang_trait_fn(db, LangItem::Not, &name![not])?,
403+
ast::UnaryOp::Neg => self.lang_trait_fn(db, LangItem::Neg, &name![neg])?,
384404
};
405+
385406
let ty = self.ty_of_expr(db, &prefix_expr.expr()?)?;
386407

387-
let (op_trait, op_fn) = self.lang_trait_fn(db, lang_item, &fn_name)?;
388408
// HACK: subst for all methods coincides with that for their trait because the methods
389409
// don't have any generic parameters, so we skip building another subst for the methods.
390410
let substs = hir_ty::TyBuilder::subst_for_def(db, op_trait, None).push(ty.clone()).build();

0 commit comments

Comments
 (0)