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 base_ty = self.ty_of_expr(db, &index_expr.base()?)?;
|
||||||
let index_ty = self.ty_of_expr(db, &index_expr.index()?)?;
|
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
|
// 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.
|
// 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)
|
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]
|
#[test]
|
||||||
fn goto_prefix_op() {
|
fn goto_prefix_op() {
|
||||||
check(
|
check(
|
||||||
|
|
Loading…
Reference in a new issue