@@ -3,7 +3,9 @@ use crate::{
33 assist_context:: { AssistContext , Assists } ,
44 utils:: add_cfg_attrs_to,
55} ;
6+ use hir:: Semantics ;
67use ide_db:: {
8+ RootDatabase ,
79 assists:: { AssistId , AssistKind , ExprFillDefaultMode } ,
810 syntax_helpers:: suggest_name,
911} ;
@@ -61,6 +63,11 @@ pub(crate) fn generate_blanket_trait_impl(
6163 let name = ctx. find_node_at_offset :: < ast:: Name > ( ) ?;
6264 let traitd = ast:: Trait :: cast ( name. syntax ( ) . parent ( ) ?) ?;
6365
66+ if existing_any_impl ( & traitd, & ctx. sema ) . is_some ( ) {
67+ cov_mark:: hit!( existing_any_impl) ;
68+ return None ;
69+ }
70+
6471 acc. add (
6572 AssistId ( "generate_blanket_trait_impl" , AssistKind :: Generate , None ) ,
6673 "Generate blanket trait implementation" ,
@@ -143,6 +150,16 @@ pub(crate) fn generate_blanket_trait_impl(
143150 Some ( ( ) )
144151}
145152
153+ fn existing_any_impl ( traitd : & ast:: Trait , sema : & Semantics < ' _ , RootDatabase > ) -> Option < hir:: Impl > {
154+ let db = sema. db ;
155+ let traitd = sema. to_def ( traitd) ?;
156+ traitd
157+ . module ( db)
158+ . impl_defs ( db)
159+ . into_iter ( )
160+ . find ( |impl_| impl_. trait_ ( db) . is_some_and ( |it| it == traitd) )
161+ }
162+
146163fn has_sized ( traitd : & ast:: Trait ) -> bool {
147164 if let Some ( sized) = find_bound ( "Sized" , traitd. type_bound_list ( ) ) {
148165 sized. question_mark_token ( ) . is_none ( )
@@ -1422,6 +1439,51 @@ where
14221439 ) ;
14231440 }
14241441
1442+ #[ test]
1443+ fn test_gen_blanket_existing_impl ( ) {
1444+ cov_mark:: check!( existing_any_impl) ;
1445+ check_assist_not_applicable (
1446+ generate_blanket_trait_impl,
1447+ r#"
1448+ trait $0Foo: Default {
1449+ fn foo(&self) -> Self;
1450+ }
1451+ impl Foo for () {}
1452+ "# ,
1453+ ) ;
1454+ }
1455+
1456+ #[ test]
1457+ fn test_gen_blanket_existing_other_impl ( ) {
1458+ check_assist (
1459+ generate_blanket_trait_impl,
1460+ r#"
1461+ trait $0Foo: Default {
1462+ fn foo(&self) -> Self;
1463+ }
1464+ trait Bar: Default {
1465+ fn bar(&self) -> Self;
1466+ }
1467+ impl Bar for () {}
1468+ "# ,
1469+ r#"
1470+ trait Foo: Default {
1471+ fn foo(&self) -> Self;
1472+ }
1473+
1474+ impl<T: Default> Foo for $0T {
1475+ fn foo(&self) -> Self {
1476+ todo!()
1477+ }
1478+ }
1479+ trait Bar: Default {
1480+ fn bar(&self) -> Self;
1481+ }
1482+ impl Bar for () {}
1483+ "# ,
1484+ ) ;
1485+ }
1486+
14251487 #[ test]
14261488 fn test_gen_blanket_apply_on_other_impl_block ( ) {
14271489 check_assist (
0 commit comments