Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide-completion/src/completions/item_list/trait_impl.rs')
| -rw-r--r-- | crates/ide-completion/src/completions/item_list/trait_impl.rs | 81 |
1 files changed, 79 insertions, 2 deletions
diff --git a/crates/ide-completion/src/completions/item_list/trait_impl.rs b/crates/ide-completion/src/completions/item_list/trait_impl.rs index 664aa7b839..269e40e6ef 100644 --- a/crates/ide-completion/src/completions/item_list/trait_impl.rs +++ b/crates/ide-completion/src/completions/item_list/trait_impl.rs @@ -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) @@ -1221,6 +1223,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( "type Ty", |