Skip to content

Commit a7d0a24

Browse files
committed
Improve sized check, from super traits
1 parent ff669e9 commit a7d0a24

File tree

1 file changed

+36
-3
lines changed

1 file changed

+36
-3
lines changed

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

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@ use crate::{
33
assist_context::{AssistContext, Assists},
44
utils::add_cfg_attrs_to,
55
};
6-
use hir::Semantics;
6+
use hir::{HasCrate, Semantics};
77
use ide_db::{
88
RootDatabase,
99
assists::{AssistId, AssistKind, ExprFillDefaultMode},
10+
famous_defs::FamousDefs,
1011
syntax_helpers::suggest_name,
1112
};
1213
use syntax::{
@@ -84,7 +85,7 @@ pub(crate) fn generate_blanket_trait_impl(
8485

8586
let gendecl = make::generic_param_list([GenericParam::TypeParam(make::type_param(
8687
thisname.clone(),
87-
apply_sized(has_sized(&traitd), bounds),
88+
apply_sized(has_sized(&traitd, &ctx.sema), bounds),
8889
))]);
8990

9091
let trait_gen_args =
@@ -160,16 +161,24 @@ fn existing_any_impl(traitd: &ast::Trait, sema: &Semantics<'_, RootDatabase>) ->
160161
.find(|impl_| impl_.trait_(db).is_some_and(|it| it == traitd))
161162
}
162163

163-
fn has_sized(traitd: &ast::Trait) -> bool {
164+
fn has_sized(traitd: &ast::Trait, sema: &Semantics<'_, RootDatabase>) -> bool {
164165
if let Some(sized) = find_bound("Sized", traitd.type_bound_list()) {
165166
sized.question_mark_token().is_none()
166167
} else if let Some(is_sized) = where_clause_sized(traitd.where_clause()) {
167168
is_sized
168169
} else {
169170
contained_owned_self_method(traitd.assoc_item_list())
171+
|| super_traits_has_sized(traitd, sema) == Some(true)
170172
}
171173
}
172174

175+
fn super_traits_has_sized(traitd: &ast::Trait, sema: &Semantics<'_, RootDatabase>) -> Option<bool> {
176+
let traitd = sema.to_def(traitd)?;
177+
let sized = FamousDefs(sema, traitd.krate(sema.db)).core_marker_Sized()?;
178+
179+
Some(traitd.all_supertraits(sema.db).contains(&sized))
180+
}
181+
173182
fn contained_owned_self_method(item_list: Option<ast::AssocItemList>) -> bool {
174183
item_list.into_iter().flat_map(|assoc_item_list| assoc_item_list.assoc_items()).any(|item| {
175184
match item {
@@ -394,6 +403,30 @@ impl<T> Foo for $0T {
394403
);
395404
}
396405

406+
#[test]
407+
fn test_gen_blanket_super_sized() {
408+
check_assist(
409+
generate_blanket_trait_impl,
410+
r#"
411+
//- minicore: default
412+
trait $0Foo: Default {
413+
fn foo(&self);
414+
}
415+
"#,
416+
r#"
417+
trait Foo: Default {
418+
fn foo(&self);
419+
}
420+
421+
impl<T: Default> Foo for $0T {
422+
fn foo(&self) {
423+
todo!()
424+
}
425+
}
426+
"#,
427+
);
428+
}
429+
397430
#[test]
398431
fn test_gen_blanket_non_sized() {
399432
check_assist(

0 commit comments

Comments
 (0)