Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide-assists/src/handlers/add_missing_impl_members.rs')
| -rw-r--r-- | crates/ide-assists/src/handlers/add_missing_impl_members.rs | 87 |
1 files changed, 74 insertions, 13 deletions
diff --git a/crates/ide-assists/src/handlers/add_missing_impl_members.rs b/crates/ide-assists/src/handlers/add_missing_impl_members.rs index 0cf7a848d8..c7f9fa5bd6 100644 --- a/crates/ide-assists/src/handlers/add_missing_impl_members.rs +++ b/crates/ide-assists/src/handlers/add_missing_impl_members.rs @@ -1,5 +1,4 @@ use hir::HasSource; -use ide_db::syntax_helpers::insert_whitespace_into_node::insert_ws_into; use syntax::ast::{self, make, AstNode}; use crate::{ @@ -129,20 +128,9 @@ fn add_missing_impl_members_inner( let target = impl_def.syntax().text_range(); acc.add(AssistId(assist_id, AssistKind::QuickFix), label, target, |edit| { let new_impl_def = edit.make_mut(impl_def.clone()); - let missing_items = missing_items - .into_iter() - .map(|it| { - if ctx.sema.hir_file_for(it.syntax()).is_macro() { - if let Some(it) = ast::AssocItem::cast(insert_ws_into(it.syntax().clone())) { - return it; - } - } - it.clone_for_update() - }) - .collect(); let first_new_item = add_trait_assoc_items_to_impl( &ctx.sema, - missing_items, + &missing_items, trait_, &new_impl_def, target_scope, @@ -1730,4 +1718,77 @@ impl m::Foo for S { }"#, ) } + + #[test] + fn nested_macro_should_not_cause_crash() { + check_assist( + add_missing_impl_members, + 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 $0AnotherTrait for () { +} +"#, + 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 () { + $0fn method(&mut self,params: <ty!()as SomeTrait>::Output) { + todo!() + } +} +"#, + ); + } + + // FIXME: `T` in `ty!(T)` should be replaced by `PathTransform`. + #[test] + fn paths_in_nested_macro_should_get_transformed() { + check_assist( + add_missing_impl_members, + 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 $0AnotherTrait<i32> for () { +} +"#, + 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 () { + $0fn method(&mut self,params: <ty!(T)as SomeTrait>::Output) { + todo!() + } +} +"#, + ); + } } |