@@ -13,9 +13,6 @@ pub(crate) fn replace_impl_trait_with_generic(
1313 let type_param = type_impl_trait. syntax ( ) . parent ( ) . and_then ( ast:: Param :: cast) ?;
1414 let type_fn = type_param. syntax ( ) . ancestors ( ) . nth ( 2 ) . and_then ( ast:: Fn :: cast) ?;
1515
16- let generic_param_list =
17- type_fn. generic_param_list ( ) . unwrap_or_else ( || make:: generic_param_list ( None ) ) ;
18-
1916 let impl_trait_ty = type_impl_trait
2017 . syntax ( )
2118 . descendants ( )
@@ -31,11 +28,16 @@ pub(crate) fn replace_impl_trait_with_generic(
3128 target,
3229 |edit| {
3330 let generic_letter = impl_trait_ty[ ..1 ] . to_string ( ) ;
34- edit. replace_ast :: < ast:: Type > ( type_impl_trait. into ( ) , make:: ty ( & generic_letter) ) ;
3531
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+
3941 edit. replace_ast ( type_fn. clone ( ) , new_type_fn) ;
4042 } ,
4143 )
@@ -48,7 +50,7 @@ mod tests {
4850 use crate :: tests:: check_assist;
4951
5052 #[ test]
51- fn replace_with_generic_params ( ) {
53+ fn replace_impl_trait_with_generic_params ( ) {
5254 check_assist (
5355 replace_impl_trait_with_generic,
5456 r#"
@@ -59,4 +61,96 @@ mod tests {
5961 "# ,
6062 ) ;
6163 }
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+ }
62156}
0 commit comments