Unnamed repository; edit this file 'description' to name the repository.
Auto merge of #16709 - ShoyuVanilla:fix-goto-index-mut, r=Veykril
fix: Goto definition for `index_mut` Mostly same with #16696. https://github.com/rust-lang/rust-analyzer/blob/0ac05c05271f31c43d31017cbd288e8737a0edb0/crates/hir-ty/src/infer/mutability.rs#L103-L133 Thankfully, we are doing similar method resolutions so we can use them like the mentioned PR. As there are only three `LangItem`s having `Mut` in there names; `FnMut`, `DerefMut` and `IndexMut`, I think that this is the last one 😄
bors 2024-02-29
parent 0ac05c0 · parent bf23dee · commit 0ec6015
-rw-r--r--crates/hir/src/source_analyzer.rs17
-rw-r--r--crates/ide/src/goto_definition.rs28
2 files changed, 44 insertions, 1 deletions
diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs
index bcc9111f2b..2be47b9514 100644
--- a/crates/hir/src/source_analyzer.rs
+++ b/crates/hir/src/source_analyzer.rs
@@ -420,7 +420,22 @@ impl SourceAnalyzer {
let base_ty = self.ty_of_expr(db, &index_expr.base()?)?;
let index_ty = self.ty_of_expr(db, &index_expr.index()?)?;
- let (op_trait, op_fn) = self.lang_trait_fn(db, LangItem::Index, &name![index])?;
+ let (index_trait, index_fn) = self.lang_trait_fn(db, LangItem::Index, &name![index])?;
+ let (op_trait, op_fn) = self
+ .infer
+ .as_ref()
+ .and_then(|infer| {
+ let expr = self.expr_id(db, &index_expr.clone().into())?;
+ let (func, _) = infer.method_resolution(expr)?;
+ let (index_mut_trait, index_mut_fn) =
+ self.lang_trait_fn(db, LangItem::IndexMut, &name![index_mut])?;
+ if func == index_mut_fn {
+ Some((index_mut_trait, index_mut_fn))
+ } else {
+ None
+ }
+ })
+ .unwrap_or((index_trait, index_fn));
// HACK: subst for all methods coincides with that for their trait because the methods
// don't have any generic parameters, so we skip building another subst for the methods.
let substs = hir_ty::TyBuilder::subst_for_def(db, op_trait, None)
diff --git a/crates/ide/src/goto_definition.rs b/crates/ide/src/goto_definition.rs
index 35efe144e1..41148db614 100644
--- a/crates/ide/src/goto_definition.rs
+++ b/crates/ide/src/goto_definition.rs
@@ -1956,6 +1956,34 @@ fn f() {
}
#[test]
+ fn goto_index_mut_op() {
+ check(
+ r#"
+//- minicore: index
+
+struct Foo;
+struct Bar;
+
+impl core::ops::Index<usize> for Foo {
+ type Output = Bar;
+
+ fn index(&self, index: usize) -> &Self::Output {}
+}
+
+impl core::ops::IndexMut<usize> for Foo {
+ fn index_mut(&mut self, index: usize) -> &mut Self::Output {}
+ //^^^^^^^^^
+}
+
+fn f() {
+ let mut foo = Foo;
+ foo[0]$0 = Bar;
+}
+"#,
+ );
+ }
+
+ #[test]
fn goto_prefix_op() {
check(
r#"