@@ -9,42 +9,38 @@ use syntax::{
9
9
10
10
use crate :: { AssistContext , Assists } ;
11
11
12
- // Assist: toggle_async_sugar
12
+ // Assist: sugar_impl_future_into_async
13
13
//
14
- // Rewrites asynchronous function into `impl Future` and back .
14
+ // Rewrites asynchronous function from `impl Future` to `async fn` .
15
15
// This action does not touch the function body and therefore `async { 0 }`
16
16
// block does not transform to just `0`.
17
17
//
18
18
// ```
19
- // pub async f$0n foo() -> usize {
20
- // 0
19
+ // # //- minicore: future
20
+ // pub f$0n foo() -> impl core::future::Future<Output = usize> {
21
+ // async { 0 }
21
22
// }
22
23
// ```
23
24
// ->
24
25
// ```
25
- // pub fn foo() -> impl Future<Output = usize> {
26
- // 0
26
+ // pub async fn foo() -> usize {
27
+ // async { 0 }
27
28
// }
28
29
// ```
29
- pub ( crate ) fn toggle_async_sugar ( acc : & mut Assists , ctx : & AssistContext < ' _ > ) -> Option < ( ) > {
30
- let function: ast:: Fn = ctx. find_node_at_offset ( ) ?;
31
- match ( function. async_token ( ) , function. ret_type ( ) ) {
32
- // async function returning futures cannot be flattened
33
- // const async is not yet supported
34
- ( None , Some ( ret_type) ) if function. const_token ( ) . is_none ( ) => {
35
- add_async ( acc, ctx, function, ret_type)
36
- }
37
- ( Some ( async_token) , ret_type) => remove_async ( function, ret_type, acc, async_token) ,
38
- _ => None ,
39
- }
40
- }
41
-
42
- fn add_async (
30
+ pub ( crate ) fn sugar_impl_future_into_async (
43
31
acc : & mut Assists ,
44
32
ctx : & AssistContext < ' _ > ,
45
- function : ast:: Fn ,
46
- ret_type : ast:: RetType ,
47
33
) -> Option < ( ) > {
34
+ let function: ast:: Fn = ctx. find_node_at_offset ( ) ?;
35
+ if function. async_token ( ) . is_some ( ) {
36
+ return None ;
37
+ }
38
+
39
+ let ret_type = function. ret_type ( ) ?;
40
+ if function. const_token ( ) . is_some ( ) {
41
+ return None ;
42
+ }
43
+
48
44
let ast:: Type :: ImplTraitType ( return_impl_trait) = ret_type. ty ( ) ? else {
49
45
return None ;
50
46
} ;
@@ -66,12 +62,12 @@ fn add_async(
66
62
let future_output = unwrap_future_output ( main_trait_path) ?;
67
63
68
64
acc. add (
69
- AssistId ( "toggle_async_sugar " , AssistKind :: RefactorRewrite ) ,
65
+ AssistId ( "sugar_impl_future_into_async " , AssistKind :: RefactorRewrite ) ,
70
66
"Convert `impl Future` into async" ,
71
67
function. syntax ( ) . text_range ( ) ,
72
68
|builder| {
73
69
match future_output {
74
- ast:: Type :: TupleType ( _ ) => {
70
+ ast:: Type :: TupleType ( t ) if t . fields ( ) . next ( ) . is_none ( ) => {
75
71
let mut ret_type_range = ret_type. syntax ( ) . text_range ( ) ;
76
72
77
73
// find leftover whitespace
@@ -105,22 +101,40 @@ fn add_async(
105
101
)
106
102
}
107
103
108
- fn remove_async (
109
- function : ast:: Fn ,
110
- ret_type : Option < ast:: RetType > ,
104
+ // Assist: desugar_async_into_impl_future
105
+ //
106
+ // Rewrites asynchronous function from `async fn` to `impl Future`.
107
+ // This action does not touch the function body and therefore `0`
108
+ // block does not transform to `async { 0 }`.
109
+ //
110
+ // ```
111
+ // pub async f$0n foo() -> usize {
112
+ // 0
113
+ // }
114
+ // ```
115
+ // ->
116
+ // ```
117
+ // pub fn foo() -> impl Future<Output = usize> {
118
+ // 0
119
+ // }
120
+ // ```
121
+ pub ( crate ) fn desugar_async_into_impl_future (
111
122
acc : & mut Assists ,
112
- async_token : SyntaxToken ,
123
+ ctx : & AssistContext < ' _ > ,
113
124
) -> Option < ( ) > {
125
+ let function: ast:: Fn = ctx. find_node_at_offset ( ) ?;
126
+ let async_token = function. async_token ( ) ?;
127
+
114
128
let rparen = function. param_list ( ) ?. r_paren_token ( ) ?;
115
- let return_type = match ret_type {
129
+ let return_type = match function . ret_type ( ) {
116
130
// unable to get a `ty` makes the action unapplicable
117
131
Some ( ret_type) => Some ( ret_type. ty ( ) ?) ,
118
132
// No type means `-> ()`
119
133
None => None ,
120
134
} ;
121
135
122
136
acc. add (
123
- AssistId ( "toggle_async_sugar " , AssistKind :: RefactorRewrite ) ,
137
+ AssistId ( "desugar_async_into_impl_future " , AssistKind :: RefactorRewrite ) ,
124
138
"Convert async into `impl Future`" ,
125
139
function. syntax ( ) . text_range ( ) ,
126
140
|builder| {
@@ -168,7 +182,7 @@ mod tests {
168
182
#[ test]
169
183
fn sugar_with_use ( ) {
170
184
check_assist (
171
- toggle_async_sugar ,
185
+ sugar_impl_future_into_async ,
172
186
r#"
173
187
//- minicore: future
174
188
use core::future::Future;
@@ -185,7 +199,7 @@ mod tests {
185
199
) ;
186
200
187
201
check_assist (
188
- toggle_async_sugar ,
202
+ sugar_impl_future_into_async ,
189
203
r#"
190
204
//- minicore: future
191
205
use core::future::Future;
@@ -205,7 +219,7 @@ mod tests {
205
219
#[ test]
206
220
fn desugar_with_use ( ) {
207
221
check_assist (
208
- toggle_async_sugar ,
222
+ desugar_async_into_impl_future ,
209
223
r#"
210
224
//- minicore: future
211
225
use core::future::Future;
@@ -222,7 +236,7 @@ mod tests {
222
236
) ;
223
237
224
238
check_assist (
225
- toggle_async_sugar ,
239
+ desugar_async_into_impl_future ,
226
240
r#"
227
241
//- minicore: future
228
242
use core::future::Future;
@@ -242,7 +256,7 @@ mod tests {
242
256
#[ test]
243
257
fn sugar_without_use ( ) {
244
258
check_assist (
245
- toggle_async_sugar ,
259
+ sugar_impl_future_into_async ,
246
260
r#"
247
261
//- minicore: future
248
262
f$0n foo() -> impl core::future::Future<Output = ()> {
@@ -257,7 +271,7 @@ mod tests {
257
271
) ;
258
272
259
273
check_assist (
260
- toggle_async_sugar ,
274
+ sugar_impl_future_into_async ,
261
275
r#"
262
276
//- minicore: future
263
277
f$0n foo() -> impl core::future::Future<Output = usize> {
@@ -275,7 +289,7 @@ mod tests {
275
289
#[ test]
276
290
fn desugar_without_use ( ) {
277
291
check_assist (
278
- toggle_async_sugar ,
292
+ desugar_async_into_impl_future ,
279
293
r#"
280
294
//- minicore: future
281
295
async f$0n foo() {
@@ -290,7 +304,7 @@ mod tests {
290
304
) ;
291
305
292
306
check_assist (
293
- toggle_async_sugar ,
307
+ desugar_async_into_impl_future ,
294
308
r#"
295
309
//- minicore: future
296
310
async f$0n foo() -> usize {
@@ -308,7 +322,7 @@ mod tests {
308
322
#[ test]
309
323
fn sugar_not_applicable ( ) {
310
324
check_assist_not_applicable (
311
- toggle_async_sugar ,
325
+ sugar_impl_future_into_async ,
312
326
r#"
313
327
//- minicore: future
314
328
trait Future {
@@ -321,7 +335,7 @@ mod tests {
321
335
) ;
322
336
323
337
check_assist_not_applicable (
324
- toggle_async_sugar ,
338
+ sugar_impl_future_into_async ,
325
339
r#"
326
340
//- minicore: future
327
341
trait Future {
@@ -337,7 +351,7 @@ mod tests {
337
351
#[ test]
338
352
fn sugar_definition_with_use ( ) {
339
353
check_assist (
340
- toggle_async_sugar ,
354
+ sugar_impl_future_into_async ,
341
355
r#"
342
356
//- minicore: future
343
357
use core::future::Future;
@@ -350,7 +364,7 @@ mod tests {
350
364
) ;
351
365
352
366
check_assist (
353
- toggle_async_sugar ,
367
+ sugar_impl_future_into_async ,
354
368
r#"
355
369
//- minicore: future
356
370
use core::future::Future;
@@ -366,7 +380,7 @@ mod tests {
366
380
#[ test]
367
381
fn sugar_definition_without_use ( ) {
368
382
check_assist (
369
- toggle_async_sugar ,
383
+ sugar_impl_future_into_async ,
370
384
r#"
371
385
//- minicore: future
372
386
f$0n foo() -> impl core::future::Future<Output = ()>;
@@ -377,7 +391,7 @@ mod tests {
377
391
) ;
378
392
379
393
check_assist (
380
- toggle_async_sugar ,
394
+ sugar_impl_future_into_async ,
381
395
r#"
382
396
//- minicore: future
383
397
f$0n foo() -> impl core::future::Future<Output = usize>;
@@ -388,18 +402,65 @@ mod tests {
388
402
) ;
389
403
}
390
404
405
+ #[ test]
406
+ fn sugar_more_types ( ) {
407
+ check_assist (
408
+ sugar_impl_future_into_async,
409
+ r#"
410
+ //- minicore: future
411
+ f$0n foo() -> impl core::future::Future<Output = ()> + Send + Sync;
412
+ "# ,
413
+ r#"
414
+ async fn foo();
415
+ "# ,
416
+ ) ;
417
+
418
+ check_assist (
419
+ sugar_impl_future_into_async,
420
+ r#"
421
+ //- minicore: future
422
+ f$0n foo() -> impl core::future::Future<Output = usize> + Debug;
423
+ "# ,
424
+ r#"
425
+ async fn foo() -> usize;
426
+ "# ,
427
+ ) ;
428
+
429
+ check_assist (
430
+ sugar_impl_future_into_async,
431
+ r#"
432
+ //- minicore: future
433
+ f$0n foo() -> impl core::future::Future<Output = (usize)> + Debug;
434
+ "# ,
435
+ r#"
436
+ async fn foo() -> (usize);
437
+ "# ,
438
+ ) ;
439
+
440
+ check_assist (
441
+ sugar_impl_future_into_async,
442
+ r#"
443
+ //- minicore: future
444
+ f$0n foo() -> impl core::future::Future<Output = (usize, usize)> + Debug;
445
+ "# ,
446
+ r#"
447
+ async fn foo() -> (usize, usize);
448
+ "# ,
449
+ ) ;
450
+ }
451
+
391
452
#[ test]
392
453
fn sugar_with_modifiers ( ) {
393
454
check_assist_not_applicable (
394
- toggle_async_sugar ,
455
+ sugar_impl_future_into_async ,
395
456
r#"
396
457
//- minicore: future
397
458
const f$0n foo() -> impl core::future::Future<Output = ()>;
398
459
"# ,
399
460
) ;
400
461
401
462
check_assist (
402
- toggle_async_sugar ,
463
+ sugar_impl_future_into_async ,
403
464
r#"
404
465
//- minicore: future
405
466
pub(crate) unsafe f$0n foo() -> impl core::future::Future<Output = usize>;
@@ -410,7 +471,7 @@ mod tests {
410
471
) ;
411
472
412
473
check_assist (
413
- toggle_async_sugar ,
474
+ sugar_impl_future_into_async ,
414
475
r#"
415
476
//- minicore: future
416
477
unsafe f$0n foo() -> impl core::future::Future<Output = ()>;
@@ -421,7 +482,7 @@ mod tests {
421
482
) ;
422
483
423
484
check_assist (
424
- toggle_async_sugar ,
485
+ sugar_impl_future_into_async ,
425
486
r#"
426
487
//- minicore: future
427
488
unsafe extern "C" f$0n foo() -> impl core::future::Future<Output = ()>;
@@ -432,7 +493,7 @@ mod tests {
432
493
) ;
433
494
434
495
check_assist (
435
- toggle_async_sugar ,
496
+ sugar_impl_future_into_async ,
436
497
r#"
437
498
//- minicore: future
438
499
f$0n foo<T>() -> impl core::future::Future<Output = T>;
@@ -443,7 +504,7 @@ mod tests {
443
504
) ;
444
505
445
506
check_assist (
446
- toggle_async_sugar ,
507
+ sugar_impl_future_into_async ,
447
508
r#"
448
509
//- minicore: future
449
510
f$0n foo<T>() -> impl core::future::Future<Output = T>
0 commit comments