]> git.lizzy.rs Git - rust.git/blobdiff - crates/ide_assists/src/handlers/add_missing_impl_members.rs
fix: insert whitespaces into assoc items for assist when macro generated
[rust.git] / crates / ide_assists / src / handlers / add_missing_impl_members.rs
index 87c8f5e5482784d3924e1d9edd72e184729179ff..a10eca10d11946c1b350b0e1189b56c2d91d2de1 100644 (file)
@@ -1,12 +1,12 @@
 use hir::HasSource;
-use ide_db::traits::resolve_target_trait;
+use ide_db::{helpers::insert_whitespace_into_node::insert_ws_into, traits::resolve_target_trait};
 use syntax::ast::{self, make, AstNode};
 
 use crate::{
     assist_context::{AssistContext, Assists},
     utils::{
-        add_trait_assoc_items_to_impl, filter_assoc_items, gen_trait_body, render_snippet, Cursor,
-        DefaultMethods,
+        add_trait_assoc_items_to_impl, filter_assoc_items, gen_trait_fn_body, render_snippet,
+        Cursor, DefaultMethods,
     },
     AssistId, AssistKind,
 };
@@ -105,7 +105,7 @@ fn add_missing_impl_members_inner(
     let trait_ = resolve_target_trait(&ctx.sema, &impl_def)?;
 
     let missing_items = filter_assoc_items(
-        ctx.db(),
+        &ctx.sema,
         &ide_db::traits::get_missing_assoc_items(&ctx.sema, &impl_def),
         mode,
     );
@@ -117,6 +117,17 @@ fn add_missing_impl_members_inner(
     let target = impl_def.syntax().text_range();
     acc.add(AssistId(assist_id, AssistKind::QuickFix), label, target, |builder| {
         let target_scope = ctx.sema.scope(impl_def.syntax());
+        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 (new_impl_def, first_new_item) = add_trait_assoc_items_to_impl(
             &ctx.sema,
             missing_items,
@@ -156,10 +167,10 @@ fn try_gen_trait_body(
     trait_: &hir::Trait,
     impl_def: &ast::Impl,
 ) -> Option<()> {
-    let trait_path = make::path_from_text(&trait_.name(ctx.db()).to_string());
+    let trait_path = make::ext::ident_path(&trait_.name(ctx.db()).to_string());
     let hir_ty = ctx.sema.resolve_type(&impl_def.self_ty()?)?;
     let adt = hir_ty.as_adt()?.source(ctx.db())?;
-    gen_trait_body(func, &trait_path, &adt.value)
+    gen_trait_fn_body(func, &trait_path, &adt.value)
 }
 
 #[cfg(test)]
@@ -890,6 +901,44 @@ impl Default for Foo {
         Self(Default::default())
     }
 }
+"#,
+        )
+    }
+
+    #[test]
+    fn test_from_macro() {
+        check_assist(
+            add_missing_default_members,
+            r#"
+macro_rules! foo {
+    () => {
+        trait FooB {
+            fn foo<'lt>(&'lt self) {}
+        }
+    }
+}
+foo!();
+struct Foo(usize);
+
+impl FooB for Foo {
+    $0
+}
+"#,
+            r#"
+macro_rules! foo {
+    () => {
+        trait FooB {
+            fn foo<'lt>(&'lt self) {}
+        }
+    }
+}
+foo!();
+struct Foo(usize);
+
+impl FooB for Foo {
+    $0fn foo< 'lt>(& 'lt self){}
+
+}
 "#,
         )
     }