Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--crates/ide-assists/src/handlers/generate_blanket_trait_impl.rs39
1 files changed, 36 insertions, 3 deletions
diff --git a/crates/ide-assists/src/handlers/generate_blanket_trait_impl.rs b/crates/ide-assists/src/handlers/generate_blanket_trait_impl.rs
index 1ec49f017f..dc8056e903 100644
--- a/crates/ide-assists/src/handlers/generate_blanket_trait_impl.rs
+++ b/crates/ide-assists/src/handlers/generate_blanket_trait_impl.rs
@@ -3,10 +3,11 @@ use crate::{
assist_context::{AssistContext, Assists},
utils::add_cfg_attrs_to,
};
-use hir::Semantics;
+use hir::{HasCrate, Semantics};
use ide_db::{
RootDatabase,
assists::{AssistId, AssistKind, ExprFillDefaultMode},
+ famous_defs::FamousDefs,
syntax_helpers::suggest_name,
};
use syntax::{
@@ -84,7 +85,7 @@ pub(crate) fn generate_blanket_trait_impl(
let gendecl = make::generic_param_list([GenericParam::TypeParam(make::type_param(
thisname.clone(),
- apply_sized(has_sized(&traitd), bounds),
+ apply_sized(has_sized(&traitd, &ctx.sema), bounds),
))]);
let trait_gen_args =
@@ -160,16 +161,24 @@ fn existing_any_impl(traitd: &ast::Trait, sema: &Semantics<'_, RootDatabase>) ->
.find(|impl_| impl_.trait_(db).is_some_and(|it| it == traitd))
}
-fn has_sized(traitd: &ast::Trait) -> bool {
+fn has_sized(traitd: &ast::Trait, sema: &Semantics<'_, RootDatabase>) -> bool {
if let Some(sized) = find_bound("Sized", traitd.type_bound_list()) {
sized.question_mark_token().is_none()
} else if let Some(is_sized) = where_clause_sized(traitd.where_clause()) {
is_sized
} else {
contained_owned_self_method(traitd.assoc_item_list())
+ || super_traits_has_sized(traitd, sema) == Some(true)
}
}
+fn super_traits_has_sized(traitd: &ast::Trait, sema: &Semantics<'_, RootDatabase>) -> Option<bool> {
+ let traitd = sema.to_def(traitd)?;
+ let sized = FamousDefs(sema, traitd.krate(sema.db)).core_marker_Sized()?;
+
+ Some(traitd.all_supertraits(sema.db).contains(&sized))
+}
+
fn contained_owned_self_method(item_list: Option<ast::AssocItemList>) -> bool {
item_list.into_iter().flat_map(|assoc_item_list| assoc_item_list.assoc_items()).any(|item| {
match item {
@@ -395,6 +404,30 @@ impl<T> Foo for $0T {
}
#[test]
+ fn test_gen_blanket_super_sized() {
+ check_assist(
+ generate_blanket_trait_impl,
+ r#"
+//- minicore: default
+trait $0Foo: Default {
+ fn foo(&self);
+}
+"#,
+ r#"
+trait Foo: Default {
+ fn foo(&self);
+}
+
+impl<T: Default> Foo for $0T {
+ fn foo(&self) {
+ todo!()
+ }
+}
+"#,
+ );
+ }
+
+ #[test]
fn test_gen_blanket_non_sized() {
check_assist(
generate_blanket_trait_impl,