@@ -13,9 +13,6 @@ pub(crate) fn replace_impl_trait_with_generic(
13
13
let type_param = type_impl_trait. syntax ( ) . parent ( ) . and_then ( ast:: Param :: cast) ?;
14
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
16
let impl_trait_ty = type_impl_trait
20
17
. syntax ( )
21
18
. descendants ( )
@@ -31,11 +28,16 @@ pub(crate) fn replace_impl_trait_with_generic(
31
28
target,
32
29
|edit| {
33
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
37
- . append_param ( make:: generic_param ( generic_letter, Some ( impl_trait_ty) ) ) ;
38
- let new_type_fn = type_fn. replace_descendant ( generic_param_list, new_params) ;
32
+ let generic_param_list = type_fn
33
+ . generic_param_list ( )
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
41
edit. replace_ast ( type_fn. clone ( ) , new_type_fn) ;
40
42
} ,
41
43
)
@@ -48,7 +50,7 @@ mod tests {
48
50
use crate :: tests:: check_assist;
49
51
50
52
#[ test]
51
- fn replace_with_generic_params ( ) {
53
+ fn replace_impl_trait_with_generic_params ( ) {
52
54
check_assist (
53
55
replace_impl_trait_with_generic,
54
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
}
0 commit comments