@@ -31,11 +31,13 @@ pub(crate) fn add_turbo_fish(acc: &mut Assists, ctx: &AssistContext) -> Option<(
31
31
return None ;
32
32
}
33
33
mark:: hit!( add_turbo_fish_after_call) ;
34
+ mark:: hit!( add_type_ascription_after_call) ;
34
35
arg_list. l_paren_token ( ) ?. prev_token ( ) . filter ( |it| it. kind ( ) == SyntaxKind :: IDENT )
35
36
} ) ?;
36
37
let next_token = ident. next_token ( ) ?;
37
38
if next_token. kind ( ) == T ! [ :: ] {
38
39
mark:: hit!( add_turbo_fish_one_fish_is_enough) ;
40
+ mark:: hit!( add_type_ascription_turbofished) ;
39
41
return None ;
40
42
}
41
43
let name_ref = ast:: NameRef :: cast ( ident. parent ( ) ) ?;
@@ -50,8 +52,27 @@ pub(crate) fn add_turbo_fish(acc: &mut Assists, ctx: &AssistContext) -> Option<(
50
52
let generics = hir:: GenericDef :: Function ( fun) . params ( ctx. sema . db ) ;
51
53
if generics. is_empty ( ) {
52
54
mark:: hit!( add_turbo_fish_non_generic) ;
55
+ mark:: hit!( add_type_ascription_non_generic) ;
53
56
return None ;
54
57
}
58
+
59
+ if let Some ( let_stmt) = ctx. find_node_at_offset :: < ast:: LetStmt > ( ) {
60
+ if let_stmt. colon_token ( ) . is_none ( ) {
61
+ let type_pos = let_stmt. pat ( ) ?. syntax ( ) . last_token ( ) ?. text_range ( ) . end ( ) ;
62
+ acc. add (
63
+ AssistId ( "add_type_ascription" , AssistKind :: RefactorRewrite ) ,
64
+ "Add `: _` before assignment operator" ,
65
+ ident. text_range ( ) ,
66
+ |builder| match ctx. config . snippet_cap {
67
+ Some ( cap) => builder. insert_snippet ( cap, type_pos, ": ${0:_}" ) ,
68
+ None => builder. insert ( type_pos, ": _" ) ,
69
+ } ,
70
+ ) ?
71
+ } else {
72
+ mark:: hit!( add_type_ascription_already_typed) ;
73
+ }
74
+ }
75
+
55
76
acc. add (
56
77
AssistId ( "add_turbo_fish" , AssistKind :: RefactorRewrite ) ,
57
78
"Add `::<>`" ,
@@ -65,7 +86,7 @@ pub(crate) fn add_turbo_fish(acc: &mut Assists, ctx: &AssistContext) -> Option<(
65
86
66
87
#[ cfg( test) ]
67
88
mod tests {
68
- use crate :: tests:: { check_assist, check_assist_not_applicable} ;
89
+ use crate :: tests:: { check_assist, check_assist_by_label , check_assist_not_applicable} ;
69
90
70
91
use super :: * ;
71
92
use test_utils:: mark;
@@ -158,6 +179,121 @@ fn make() -> () {}
158
179
fn main() {
159
180
make$0();
160
181
}
182
+ "# ,
183
+ ) ;
184
+ }
185
+
186
+ #[ test]
187
+ fn add_type_ascription_function ( ) {
188
+ check_assist_by_label (
189
+ add_turbo_fish,
190
+ r#"
191
+ fn make<T>() -> T {}
192
+ fn main() {
193
+ let x = make$0();
194
+ }
195
+ "# ,
196
+ r#"
197
+ fn make<T>() -> T {}
198
+ fn main() {
199
+ let x: ${0:_} = make();
200
+ }
201
+ "# ,
202
+ "Add `: _` before assignment operator" ,
203
+ ) ;
204
+ }
205
+
206
+ #[ test]
207
+ fn add_type_ascription_after_call ( ) {
208
+ mark:: check!( add_type_ascription_after_call) ;
209
+ check_assist_by_label (
210
+ add_turbo_fish,
211
+ r#"
212
+ fn make<T>() -> T {}
213
+ fn main() {
214
+ let x = make()$0;
215
+ }
216
+ "# ,
217
+ r#"
218
+ fn make<T>() -> T {}
219
+ fn main() {
220
+ let x: ${0:_} = make();
221
+ }
222
+ "# ,
223
+ "Add `: _` before assignment operator" ,
224
+ ) ;
225
+ }
226
+
227
+ #[ test]
228
+ fn add_type_ascription_method ( ) {
229
+ check_assist_by_label (
230
+ add_turbo_fish,
231
+ r#"
232
+ struct S;
233
+ impl S {
234
+ fn make<T>(&self) -> T {}
235
+ }
236
+ fn main() {
237
+ let x = S.make$0();
238
+ }
239
+ "# ,
240
+ r#"
241
+ struct S;
242
+ impl S {
243
+ fn make<T>(&self) -> T {}
244
+ }
245
+ fn main() {
246
+ let x: ${0:_} = S.make();
247
+ }
248
+ "# ,
249
+ "Add `: _` before assignment operator" ,
250
+ ) ;
251
+ }
252
+
253
+ #[ test]
254
+ fn add_type_ascription_turbofished ( ) {
255
+ mark:: check!( add_type_ascription_turbofished) ;
256
+ check_assist_not_applicable (
257
+ add_turbo_fish,
258
+ r#"
259
+ fn make<T>() -> T {}
260
+ fn main() {
261
+ let x = make$0::<()>();
262
+ }
263
+ "# ,
264
+ ) ;
265
+ }
266
+
267
+ #[ test]
268
+ fn add_type_ascription_already_typed ( ) {
269
+ mark:: check!( add_type_ascription_already_typed) ;
270
+ check_assist (
271
+ add_turbo_fish,
272
+ r#"
273
+ fn make<T>() -> T {}
274
+ fn main() {
275
+ let x: () = make$0();
276
+ }
277
+ "# ,
278
+ r#"
279
+ fn make<T>() -> T {}
280
+ fn main() {
281
+ let x: () = make::<${0:_}>();
282
+ }
283
+ "# ,
284
+ ) ;
285
+ }
286
+
287
+ #[ test]
288
+ fn add_type_ascription_non_generic ( ) {
289
+ mark:: check!( add_type_ascription_non_generic) ;
290
+ check_assist_not_applicable (
291
+ add_turbo_fish,
292
+ r#"
293
+ fn make() -> () {}
294
+ fn main() {
295
+ let x = make$0();
296
+ }
161
297
"# ,
162
298
) ;
163
299
}
0 commit comments