aboutsummaryrefslogtreecommitdiff
path: root/crates/assists/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/assists/src')
-rw-r--r--crates/assists/src/handlers/replace_impl_trait_with_generic.rs110
1 files changed, 102 insertions, 8 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 8af2d16dd..5b0d5d971 100644
--- a/crates/assists/src/handlers/replace_impl_trait_with_generic.rs
+++ b/crates/assists/src/handlers/replace_impl_trait_with_generic.rs
@@ -13,9 +13,6 @@ pub(crate) fn replace_impl_trait_with_generic(
13 let type_param = type_impl_trait.syntax().parent().and_then(ast::Param::cast)?; 13 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)?; 14 let type_fn = type_param.syntax().ancestors().nth(2).and_then(ast::Fn::cast)?;
15 15
16 let generic_param_list =
17 type_fn.generic_param_list().unwrap_or_else(|| make::generic_param_list(None));
18
19 let impl_trait_ty = type_impl_trait 16 let impl_trait_ty = type_impl_trait
20 .syntax() 17 .syntax()
21 .descendants() 18 .descendants()
@@ -31,11 +28,16 @@ pub(crate) fn replace_impl_trait_with_generic(
31 target, 28 target,
32 |edit| { 29 |edit| {
33 let generic_letter = impl_trait_ty[..1].to_string(); 30 let generic_letter = impl_trait_ty[..1].to_string();
34 edit.replace_ast::<ast::Type>(type_impl_trait.into(), make::ty(&generic_letter));
35 31
36 let new_params = generic_param_list 32 let generic_param_list = type_fn
37 .append_param(make::generic_param(generic_letter, Some(impl_trait_ty))); 33 .generic_param_list()
38 let new_type_fn = type_fn.replace_descendant(generic_param_list, new_params); 34 .unwrap_or_else(|| make::generic_param_list(None))
35 .append_param(make::generic_param(generic_letter.clone(), Some(impl_trait_ty)));
36
37 let new_type_fn = type_fn
38 .replace_descendant::<ast::Type>(type_impl_trait.into(), make::ty(&generic_letter))
39 .with_generic_params(generic_param_list);
40
39 edit.replace_ast(type_fn.clone(), new_type_fn); 41 edit.replace_ast(type_fn.clone(), new_type_fn);
40 }, 42 },
41 ) 43 )
@@ -48,7 +50,7 @@ mod tests {
48 use crate::tests::check_assist; 50 use crate::tests::check_assist;
49 51
50 #[test] 52 #[test]
51 fn replace_with_generic_params() { 53 fn replace_impl_trait_with_generic_params() {
52 check_assist( 54 check_assist(
53 replace_impl_trait_with_generic, 55 replace_impl_trait_with_generic,
54 r#" 56 r#"
@@ -59,4 +61,96 @@ mod tests {
59 "#, 61 "#,
60 ); 62 );
61 } 63 }
64
65 #[test]
66 fn replace_impl_trait_without_generic_params() {
67 check_assist(
68 replace_impl_trait_with_generic,
69 r#"
70 fn foo(bar: <|>impl Bar) {}
71 "#,
72 r#"
73 fn foo<B: Bar>(bar: B) {}
74 "#,
75 );
76 }
77
78 #[test]
79 fn replace_two_impl_trait_with_generic_params() {
80 check_assist(
81 replace_impl_trait_with_generic,
82 r#"
83 fn foo<G>(foo: impl Foo, bar: <|>impl Bar) {}
84 "#,
85 r#"
86 fn foo<G, B: Bar>(foo: impl Foo, bar: B) {}
87 "#,
88 );
89 }
90
91 #[test]
92 fn replace_impl_trait_with_empty_generic_params() {
93 check_assist(
94 replace_impl_trait_with_generic,
95 r#"
96 fn foo<>(bar: <|>impl Bar) {}
97 "#,
98 r#"
99 fn foo<B: Bar>(bar: B) {}
100 "#,
101 );
102 }
103
104 #[test]
105 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(
109 replace_impl_trait_with_generic,
110 r#"
111 fn foo<
112 >(bar: <|>impl Bar) {}
113 "#,
114 r#"
115 fn foo<B: Bar,
116 >(bar: B) {}
117 "#,
118 );
119 }
120
121 #[test]
122 #[ignore = "This case is very rare but there is no simple solutions to fix it."]
123 fn replace_impl_trait_with_exist_generic_letter() {
124 check_assist(
125 replace_impl_trait_with_generic,
126 r#"
127 fn foo<B>(bar: <|>impl Bar) {}
128 "#,
129 r#"
130 fn foo<B, C: Bar>(bar: C) {}
131 "#,
132 );
133 }
134
135 #[test]
136 fn replace_impl_trait_with_multiline_generic_params() {
137 check_assist(
138 replace_impl_trait_with_generic,
139 r#"
140 fn foo<
141 G: Foo,
142 F,
143 H,
144 >(bar: <|>impl Bar) {}
145 "#,
146 r#"
147 fn foo<
148 G: Foo,
149 F,
150 H,
151 B: Bar,
152 >(bar: B) {}
153 "#,
154 );
155 }
62} 156}