mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-15 22:54:00 +00:00
Auto merge of #16709 - ShoyuVanilla:fix-goto-index-mut, r=Veykril
fix: Goto definition for `index_mut`
Mostly same with #16696.
0ac05c0527/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 😄
This commit is contained in:
commit
0ec6015b6e
2 changed files with 44 additions and 1 deletions
|
@ -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)
|
||||
|
|
|
@ -1955,6 +1955,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(
|
||||
|
|
Loading…
Reference in a new issue