Skip to content

Commit ff669e9

Browse files
committed
Add existing any implement not applicate blanket
1 parent 19c5248 commit ff669e9

File tree

1 file changed

+62
-0
lines changed

1 file changed

+62
-0
lines changed

crates/ide-assists/src/handlers/generate_blanket_trait_impl.rs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ use crate::{
33
assist_context::{AssistContext, Assists},
44
utils::add_cfg_attrs_to,
55
};
6+
use hir::Semantics;
67
use 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+
146163
fn 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

Comments
 (0)