Skip to content

Commit 6c7be6c

Browse files
Merge #10734
10734: fix: add generic parameters in convert to manual impl assist r=Veykril a=TheDoctor314 Fixes #10041. Co-authored-by: TheDoctor314 <[email protected]>
2 parents 7e756ac + 58a24de commit 6c7be6c

File tree

2 files changed

+74
-4
lines changed

2 files changed

+74
-4
lines changed

crates/ide_assists/src/handlers/replace_derive_with_manual_impl.rs

Lines changed: 67 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,8 +160,25 @@ fn impl_def_from_trait(
160160
if trait_items.is_empty() {
161161
return None;
162162
}
163-
let impl_def =
164-
make::impl_trait(trait_path.clone(), make::ext::ident_path(&annotated_name.text()));
163+
let impl_def = {
164+
use syntax::ast::Impl;
165+
let text = generate_trait_impl_text(adt, trait_path.to_string().as_str(), "");
166+
let parse = syntax::SourceFile::parse(&text);
167+
let node = match parse.tree().syntax().descendants().find_map(Impl::cast) {
168+
Some(it) => it,
169+
None => {
170+
panic!(
171+
"Failed to make ast node `{}` from text {}",
172+
std::any::type_name::<Impl>(),
173+
text
174+
)
175+
}
176+
};
177+
let node = node.clone_subtree();
178+
assert_eq!(node.syntax().text_range().start(), 0.into());
179+
node
180+
};
181+
165182
let (impl_def, first_assoc_item) =
166183
add_trait_assoc_items_to_impl(sema, trait_items, trait_, impl_def, target_scope);
167184

@@ -1048,6 +1065,54 @@ impl Debug for Foo {
10481065
)
10491066
}
10501067

1068+
#[test]
1069+
fn add_custom_impl_default_generic_record_struct() {
1070+
check_assist(
1071+
replace_derive_with_manual_impl,
1072+
r#"
1073+
//- minicore: default
1074+
#[derive(Defau$0lt)]
1075+
struct Foo<T, U> {
1076+
foo: T,
1077+
bar: U,
1078+
}
1079+
"#,
1080+
r#"
1081+
struct Foo<T, U> {
1082+
foo: T,
1083+
bar: U,
1084+
}
1085+
1086+
impl<T, U> Default for Foo<T, U> {
1087+
$0fn default() -> Self {
1088+
Self { foo: Default::default(), bar: Default::default() }
1089+
}
1090+
}
1091+
"#,
1092+
)
1093+
}
1094+
1095+
#[test]
1096+
fn add_custom_impl_clone_generic_tuple_struct_with_bounds() {
1097+
check_assist(
1098+
replace_derive_with_manual_impl,
1099+
r#"
1100+
//- minicore: clone
1101+
#[derive(Clo$0ne)]
1102+
struct Foo<T: Clone>(T, usize);
1103+
"#,
1104+
r#"
1105+
struct Foo<T: Clone>(T, usize);
1106+
1107+
impl<T: Clone> Clone for Foo<T> {
1108+
$0fn clone(&self) -> Self {
1109+
Self(self.0.clone(), self.1.clone())
1110+
}
1111+
}
1112+
"#,
1113+
)
1114+
}
1115+
10511116
#[test]
10521117
fn test_ignore_derive_macro_without_input() {
10531118
check_assist_not_applicable(

crates/syntax/src/ast/make.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,8 +149,13 @@ pub fn impl_(
149149
ast_from_text(&format!("impl{} {}{} {{}}", params, ty, ty_params))
150150
}
151151

152-
pub fn impl_trait(trait_: ast::Path, ty: ast::Path) -> ast::Impl {
153-
ast_from_text(&format!("impl {} for {} {{}}", trait_, ty))
152+
pub fn impl_trait(
153+
trait_: ast::Path,
154+
ty: ast::Path,
155+
ty_params: Option<ast::GenericParamList>,
156+
) -> ast::Impl {
157+
let ty_params = ty_params.map_or_else(String::new, |params| params.to_string());
158+
ast_from_text(&format!("impl{2} {} for {}{2} {{}}", trait_, ty, ty_params))
154159
}
155160

156161
pub(crate) fn generic_arg_list() -> ast::GenericArgList {

0 commit comments

Comments
 (0)