diff options
| author | bors <bors@rust-lang.org> | 2024-02-29 13:55:23 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2024-02-29 13:55:23 +0000 |
| commit | 0ec6015b6ebe6c7691d9f6c0cd4d0e1679b336ba (patch) | |
| tree | 29a1eb07b766ae449eacc441179de933bf0561fc | |
| parent | 0ac05c05271f31c43d31017cbd288e8737a0edb0 (diff) | |
| parent | bf23deecb3523abf4235976d98da2e57df53f643 (diff) | |
| download | rust-0ec6015b6ebe6c7691d9f6c0cd4d0e1679b336ba.tar.gz rust-0ec6015b6ebe6c7691d9f6c0cd4d0e1679b336ba.zip | |
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 😄
| -rw-r--r-- | crates/hir/src/source_analyzer.rs | 17 | ||||
| -rw-r--r-- | crates/ide/src/goto_definition.rs | 28 |
2 files changed, 44 insertions, 1 deletions
diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs index bcc9111f2ba..2be47b95149 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 35efe144e1b..41148db6146 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#" |
