aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/assists/src/handlers/replace_impl_trait_with_generic.rs19
-rw-r--r--crates/syntax/src/ast/edit.rs19
2 files changed, 14 insertions, 24 deletions
diff --git a/crates/assists/src/handlers/replace_impl_trait_with_generic.rs b/crates/assists/src/handlers/replace_impl_trait_with_generic.rs
index 5b0d5d971..612c48466 100644
--- a/crates/assists/src/handlers/replace_impl_trait_with_generic.rs
+++ b/crates/assists/src/handlers/replace_impl_trait_with_generic.rs
@@ -5,13 +5,21 @@ use crate::{AssistContext, AssistId, AssistKind, Assists};
5// Assist: replace_impl_trait_with_generic 5// Assist: replace_impl_trait_with_generic
6// 6//
7// Replaces `impl Trait` function argument with the named generic. 7// Replaces `impl Trait` function argument with the named generic.
8//
9// ```
10// fn foo<G>(bar: <|>impl Bar) {}
11// ```
12// ->
13// ```
14// fn foo<B: Bar>(bar: B) {}
15// ```
8pub(crate) fn replace_impl_trait_with_generic( 16pub(crate) fn replace_impl_trait_with_generic(
9 acc: &mut Assists, 17 acc: &mut Assists,
10 ctx: &AssistContext, 18 ctx: &AssistContext,
11) -> Option<()> { 19) -> Option<()> {
12 let type_impl_trait = ctx.find_node_at_offset::<ast::ImplTraitType>()?; 20 let type_impl_trait = ctx.find_node_at_offset::<ast::ImplTraitType>()?;
13 let type_param = type_impl_trait.syntax().parent().and_then(ast::Param::cast)?; 21 let type_param = type_impl_trait.syntax().parent().and_then(ast::Param::cast)?;
14 let type_fn = type_param.syntax().ancestors().nth(2).and_then(ast::Fn::cast)?; 22 let type_fn = type_param.syntax().ancestors().find_map(ast::Fn::cast)?;
15 23
16 let impl_trait_ty = type_impl_trait 24 let impl_trait_ty = type_impl_trait
17 .syntax() 25 .syntax()
@@ -27,7 +35,7 @@ pub(crate) fn replace_impl_trait_with_generic(
27 "Replace impl trait with generic", 35 "Replace impl trait with generic",
28 target, 36 target,
29 |edit| { 37 |edit| {
30 let generic_letter = impl_trait_ty[..1].to_string(); 38 let generic_letter = impl_trait_ty.chars().next().unwrap().to_string();
31 39
32 let generic_param_list = type_fn 40 let generic_param_list = type_fn
33 .generic_param_list() 41 .generic_param_list()
@@ -36,7 +44,7 @@ pub(crate) fn replace_impl_trait_with_generic(
36 44
37 let new_type_fn = type_fn 45 let new_type_fn = type_fn
38 .replace_descendant::<ast::Type>(type_impl_trait.into(), make::ty(&generic_letter)) 46 .replace_descendant::<ast::Type>(type_impl_trait.into(), make::ty(&generic_letter))
39 .with_generic_params(generic_param_list); 47 .with_generic_param_list(generic_param_list);
40 48
41 edit.replace_ast(type_fn.clone(), new_type_fn); 49 edit.replace_ast(type_fn.clone(), new_type_fn);
42 }, 50 },
@@ -103,8 +111,6 @@ mod tests {
103 111
104 #[test] 112 #[test]
105 fn replace_impl_trait_with_empty_multiline_generic_params() { 113 fn replace_impl_trait_with_empty_multiline_generic_params() {
106 // FIXME: It would be more correct to place the generic parameter
107 // on the next line after the left angle.
108 check_assist( 114 check_assist(
109 replace_impl_trait_with_generic, 115 replace_impl_trait_with_generic,
110 r#" 116 r#"
@@ -147,8 +153,7 @@ mod tests {
147 fn foo< 153 fn foo<
148 G: Foo, 154 G: Foo,
149 F, 155 F,
150 H, 156 H, B: Bar,
151 B: Bar,
152 >(bar: B) {} 157 >(bar: B) {}
153 "#, 158 "#,
154 ); 159 );
diff --git a/crates/syntax/src/ast/edit.rs b/crates/syntax/src/ast/edit.rs
index 68987dbf6..5b5454c72 100644
--- a/crates/syntax/src/ast/edit.rs
+++ b/crates/syntax/src/ast/edit.rs
@@ -48,7 +48,7 @@ impl ast::Fn {
48 } 48 }
49 49
50 #[must_use] 50 #[must_use]
51 pub fn with_generic_params(&self, generic_args: ast::GenericParamList) -> ast::Fn { 51 pub fn with_generic_param_list(&self, generic_args: ast::GenericParamList) -> ast::Fn {
52 if let Some(old) = self.generic_param_list() { 52 if let Some(old) = self.generic_param_list() {
53 return self.replace_descendant(old, generic_args); 53 return self.replace_descendant(old, generic_args);
54 } 54 }
@@ -485,17 +485,7 @@ impl ast::GenericParamList {
485 485
486 #[must_use] 486 #[must_use]
487 pub fn append_param(&self, item: ast::GenericParam) -> ast::GenericParamList { 487 pub fn append_param(&self, item: ast::GenericParam) -> ast::GenericParamList {
488 let is_multiline = self.syntax().text().contains_char('\n'); 488 let space = tokens::single_space();
489 let ws;
490 let space = if is_multiline {
491 ws = tokens::WsBuilder::new(&format!(
492 "\n{} ",
493 leading_indent(self.syntax()).unwrap_or_default()
494 ));
495 ws.ws()
496 } else {
497 tokens::single_space()
498 };
499 489
500 let mut to_insert: ArrayVec<[SyntaxElement; 4]> = ArrayVec::new(); 490 let mut to_insert: ArrayVec<[SyntaxElement; 4]> = ArrayVec::new();
501 if self.generic_params().next().is_some() { 491 if self.generic_params().next().is_some() {
@@ -529,11 +519,6 @@ impl ast::GenericParamList {
529 }; 519 };
530 }; 520 };
531 521
532 if !is_multiline {
533 // don't insert comma before angle
534 to_insert.pop();
535 }
536
537 let position = match self.generic_params().last() { 522 let position = match self.generic_params().last() {
538 Some(it) => after_field!(it), 523 Some(it) => after_field!(it),
539 None => after_l_angle!(), 524 None => after_l_angle!(),