mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-27 21:43:37 +00:00
fix(completion): derive source scope from syntax node to be transformed
This commit is contained in:
parent
008f5065d1
commit
d091991491
2 changed files with 79 additions and 12 deletions
|
@ -483,10 +483,6 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
|
|||
self.imp.scope_at_offset(node, offset)
|
||||
}
|
||||
|
||||
pub fn scope_for_def(&self, def: Trait) -> SemanticsScope<'db> {
|
||||
self.imp.scope_for_def(def)
|
||||
}
|
||||
|
||||
pub fn assert_contains_node(&self, node: &SyntaxNode) {
|
||||
self.imp.assert_contains_node(node)
|
||||
}
|
||||
|
@ -1307,12 +1303,6 @@ impl<'db> SemanticsImpl<'db> {
|
|||
)
|
||||
}
|
||||
|
||||
fn scope_for_def(&self, def: Trait) -> SemanticsScope<'db> {
|
||||
let file_id = self.db.lookup_intern_trait(def.id).id.file_id();
|
||||
let resolver = def.id.resolver(self.db.upcast());
|
||||
SemanticsScope { db: self.db, file_id, resolver }
|
||||
}
|
||||
|
||||
fn source<Def: HasSource>(&self, def: Def) -> Option<InFile<Def::Ast>>
|
||||
where
|
||||
Def::Ast: AstNode,
|
||||
|
|
|
@ -227,9 +227,8 @@ fn get_transformed_assoc_item(
|
|||
assoc_item: ast::AssocItem,
|
||||
impl_def: hir::Impl,
|
||||
) -> Option<ast::AssocItem> {
|
||||
let assoc_item = assoc_item.clone_for_update();
|
||||
let trait_ = impl_def.trait_(ctx.db)?;
|
||||
let source_scope = &ctx.sema.scope_for_def(trait_);
|
||||
let source_scope = &ctx.sema.scope(assoc_item.syntax())?;
|
||||
let target_scope = &ctx.sema.scope(ctx.sema.source(impl_def)?.syntax().value)?;
|
||||
let transform = PathTransform::trait_impl(
|
||||
target_scope,
|
||||
|
@ -238,6 +237,9 @@ fn get_transformed_assoc_item(
|
|||
ctx.sema.source(impl_def)?.value,
|
||||
);
|
||||
|
||||
let assoc_item = assoc_item.clone_for_update();
|
||||
// FIXME: Paths in nested macros are not handled well. See
|
||||
// `macro_generated_assoc_item2` test.
|
||||
transform.apply(assoc_item.syntax());
|
||||
assoc_item.remove_attrs_and_docs();
|
||||
Some(assoc_item)
|
||||
|
@ -1220,6 +1222,81 @@ impl Foo for Test {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn macro_generated_assoc_item() {
|
||||
check_edit(
|
||||
"fn method",
|
||||
r#"
|
||||
macro_rules! ty { () => { i32 } }
|
||||
trait SomeTrait { type Output; }
|
||||
impl SomeTrait for i32 { type Output = i64; }
|
||||
macro_rules! define_method {
|
||||
() => {
|
||||
fn method(&mut self, params: <ty!() as SomeTrait>::Output);
|
||||
};
|
||||
}
|
||||
trait AnotherTrait { define_method!(); }
|
||||
impl AnotherTrait for () {
|
||||
$0
|
||||
}
|
||||
"#,
|
||||
r#"
|
||||
macro_rules! ty { () => { i32 } }
|
||||
trait SomeTrait { type Output; }
|
||||
impl SomeTrait for i32 { type Output = i64; }
|
||||
macro_rules! define_method {
|
||||
() => {
|
||||
fn method(&mut self, params: <ty!() as SomeTrait>::Output);
|
||||
};
|
||||
}
|
||||
trait AnotherTrait { define_method!(); }
|
||||
impl AnotherTrait for () {
|
||||
fn method(&mut self,params: <ty!()as SomeTrait>::Output) {
|
||||
$0
|
||||
}
|
||||
}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
||||
// FIXME: `T` in `ty!(T)` should be replaced by `PathTransform`.
|
||||
#[test]
|
||||
fn macro_generated_assoc_item2() {
|
||||
check_edit(
|
||||
"fn method",
|
||||
r#"
|
||||
macro_rules! ty { ($me:ty) => { $me } }
|
||||
trait SomeTrait { type Output; }
|
||||
impl SomeTrait for i32 { type Output = i64; }
|
||||
macro_rules! define_method {
|
||||
($t:ty) => {
|
||||
fn method(&mut self, params: <ty!($t) as SomeTrait>::Output);
|
||||
};
|
||||
}
|
||||
trait AnotherTrait<T: SomeTrait> { define_method!(T); }
|
||||
impl AnotherTrait<i32> for () {
|
||||
$0
|
||||
}
|
||||
"#,
|
||||
r#"
|
||||
macro_rules! ty { ($me:ty) => { $me } }
|
||||
trait SomeTrait { type Output; }
|
||||
impl SomeTrait for i32 { type Output = i64; }
|
||||
macro_rules! define_method {
|
||||
($t:ty) => {
|
||||
fn method(&mut self, params: <ty!($t) as SomeTrait>::Output);
|
||||
};
|
||||
}
|
||||
trait AnotherTrait<T: SomeTrait> { define_method!(T); }
|
||||
impl AnotherTrait<i32> for () {
|
||||
fn method(&mut self,params: <ty!(T)as SomeTrait>::Output) {
|
||||
$0
|
||||
}
|
||||
}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn includes_gat_generics() {
|
||||
check_edit(
|
||||
|
|
Loading…
Reference in a new issue