@@ -9,42 +9,38 @@ use syntax::{
99
1010use crate :: { AssistContext , Assists } ;
1111
12- // Assist: toggle_async_sugar
12+ // Assist: sugar_impl_future_into_async
1313//
14- // Rewrites asynchronous function into `impl Future` and back .
14+ // Rewrites asynchronous function from `impl Future` to `async fn` .
1515// This action does not touch the function body and therefore `async { 0 }`
1616// block does not transform to just `0`.
1717//
1818// ```
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 }
2122// }
2223// ```
2324// ->
2425// ```
25- // pub fn foo() -> impl Future<Output = usize> {
26- // 0
26+ // pub async fn foo() -> usize {
27+ // async { 0 }
2728// }
2829// ```
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 (
4331 acc : & mut Assists ,
4432 ctx : & AssistContext < ' _ > ,
45- function : ast:: Fn ,
46- ret_type : ast:: RetType ,
4733) -> 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+
4844 let ast:: Type :: ImplTraitType ( return_impl_trait) = ret_type. ty ( ) ? else {
4945 return None ;
5046 } ;
@@ -66,12 +62,12 @@ fn add_async(
6662 let future_output = unwrap_future_output ( main_trait_path) ?;
6763
6864 acc. add (
69- AssistId ( "toggle_async_sugar " , AssistKind :: RefactorRewrite ) ,
65+ AssistId ( "sugar_impl_future_into_async " , AssistKind :: RefactorRewrite ) ,
7066 "Convert `impl Future` into async" ,
7167 function. syntax ( ) . text_range ( ) ,
7268 |builder| {
7369 match future_output {
74- ast:: Type :: TupleType ( _ ) => {
70+ ast:: Type :: TupleType ( t ) if t . fields ( ) . next ( ) . is_none ( ) => {
7571 let mut ret_type_range = ret_type. syntax ( ) . text_range ( ) ;
7672
7773 // find leftover whitespace
@@ -105,22 +101,40 @@ fn add_async(
105101 )
106102}
107103
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 (
111122 acc : & mut Assists ,
112- async_token : SyntaxToken ,
123+ ctx : & AssistContext < ' _ > ,
113124) -> Option < ( ) > {
125+ let function: ast:: Fn = ctx. find_node_at_offset ( ) ?;
126+ let async_token = function. async_token ( ) ?;
127+
114128 let rparen = function. param_list ( ) ?. r_paren_token ( ) ?;
115- let return_type = match ret_type {
129+ let return_type = match function . ret_type ( ) {
116130 // unable to get a `ty` makes the action unapplicable
117131 Some ( ret_type) => Some ( ret_type. ty ( ) ?) ,
118132 // No type means `-> ()`
119133 None => None ,
120134 } ;
121135
122136 acc. add (
123- AssistId ( "toggle_async_sugar " , AssistKind :: RefactorRewrite ) ,
137+ AssistId ( "desugar_async_into_impl_future " , AssistKind :: RefactorRewrite ) ,
124138 "Convert async into `impl Future`" ,
125139 function. syntax ( ) . text_range ( ) ,
126140 |builder| {
@@ -168,7 +182,7 @@ mod tests {
168182 #[ test]
169183 fn sugar_with_use ( ) {
170184 check_assist (
171- toggle_async_sugar ,
185+ sugar_impl_future_into_async ,
172186 r#"
173187 //- minicore: future
174188 use core::future::Future;
@@ -185,7 +199,7 @@ mod tests {
185199 ) ;
186200
187201 check_assist (
188- toggle_async_sugar ,
202+ sugar_impl_future_into_async ,
189203 r#"
190204 //- minicore: future
191205 use core::future::Future;
@@ -205,7 +219,7 @@ mod tests {
205219 #[ test]
206220 fn desugar_with_use ( ) {
207221 check_assist (
208- toggle_async_sugar ,
222+ desugar_async_into_impl_future ,
209223 r#"
210224 //- minicore: future
211225 use core::future::Future;
@@ -222,7 +236,7 @@ mod tests {
222236 ) ;
223237
224238 check_assist (
225- toggle_async_sugar ,
239+ desugar_async_into_impl_future ,
226240 r#"
227241 //- minicore: future
228242 use core::future::Future;
@@ -242,7 +256,7 @@ mod tests {
242256 #[ test]
243257 fn sugar_without_use ( ) {
244258 check_assist (
245- toggle_async_sugar ,
259+ sugar_impl_future_into_async ,
246260 r#"
247261 //- minicore: future
248262 f$0n foo() -> impl core::future::Future<Output = ()> {
@@ -257,7 +271,7 @@ mod tests {
257271 ) ;
258272
259273 check_assist (
260- toggle_async_sugar ,
274+ sugar_impl_future_into_async ,
261275 r#"
262276 //- minicore: future
263277 f$0n foo() -> impl core::future::Future<Output = usize> {
@@ -275,7 +289,7 @@ mod tests {
275289 #[ test]
276290 fn desugar_without_use ( ) {
277291 check_assist (
278- toggle_async_sugar ,
292+ desugar_async_into_impl_future ,
279293 r#"
280294 //- minicore: future
281295 async f$0n foo() {
@@ -290,7 +304,7 @@ mod tests {
290304 ) ;
291305
292306 check_assist (
293- toggle_async_sugar ,
307+ desugar_async_into_impl_future ,
294308 r#"
295309 //- minicore: future
296310 async f$0n foo() -> usize {
@@ -308,7 +322,7 @@ mod tests {
308322 #[ test]
309323 fn sugar_not_applicable ( ) {
310324 check_assist_not_applicable (
311- toggle_async_sugar ,
325+ sugar_impl_future_into_async ,
312326 r#"
313327 //- minicore: future
314328 trait Future {
@@ -321,7 +335,7 @@ mod tests {
321335 ) ;
322336
323337 check_assist_not_applicable (
324- toggle_async_sugar ,
338+ sugar_impl_future_into_async ,
325339 r#"
326340 //- minicore: future
327341 trait Future {
@@ -337,7 +351,7 @@ mod tests {
337351 #[ test]
338352 fn sugar_definition_with_use ( ) {
339353 check_assist (
340- toggle_async_sugar ,
354+ sugar_impl_future_into_async ,
341355 r#"
342356 //- minicore: future
343357 use core::future::Future;
@@ -350,7 +364,7 @@ mod tests {
350364 ) ;
351365
352366 check_assist (
353- toggle_async_sugar ,
367+ sugar_impl_future_into_async ,
354368 r#"
355369 //- minicore: future
356370 use core::future::Future;
@@ -366,7 +380,7 @@ mod tests {
366380 #[ test]
367381 fn sugar_definition_without_use ( ) {
368382 check_assist (
369- toggle_async_sugar ,
383+ sugar_impl_future_into_async ,
370384 r#"
371385 //- minicore: future
372386 f$0n foo() -> impl core::future::Future<Output = ()>;
@@ -377,7 +391,7 @@ mod tests {
377391 ) ;
378392
379393 check_assist (
380- toggle_async_sugar ,
394+ sugar_impl_future_into_async ,
381395 r#"
382396 //- minicore: future
383397 f$0n foo() -> impl core::future::Future<Output = usize>;
@@ -388,18 +402,65 @@ mod tests {
388402 ) ;
389403 }
390404
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+
391452 #[ test]
392453 fn sugar_with_modifiers ( ) {
393454 check_assist_not_applicable (
394- toggle_async_sugar ,
455+ sugar_impl_future_into_async ,
395456 r#"
396457 //- minicore: future
397458 const f$0n foo() -> impl core::future::Future<Output = ()>;
398459 "# ,
399460 ) ;
400461
401462 check_assist (
402- toggle_async_sugar ,
463+ sugar_impl_future_into_async ,
403464 r#"
404465 //- minicore: future
405466 pub(crate) unsafe f$0n foo() -> impl core::future::Future<Output = usize>;
@@ -410,7 +471,7 @@ mod tests {
410471 ) ;
411472
412473 check_assist (
413- toggle_async_sugar ,
474+ sugar_impl_future_into_async ,
414475 r#"
415476 //- minicore: future
416477 unsafe f$0n foo() -> impl core::future::Future<Output = ()>;
@@ -421,7 +482,7 @@ mod tests {
421482 ) ;
422483
423484 check_assist (
424- toggle_async_sugar ,
485+ sugar_impl_future_into_async ,
425486 r#"
426487 //- minicore: future
427488 unsafe extern "C" f$0n foo() -> impl core::future::Future<Output = ()>;
@@ -432,7 +493,7 @@ mod tests {
432493 ) ;
433494
434495 check_assist (
435- toggle_async_sugar ,
496+ sugar_impl_future_into_async ,
436497 r#"
437498 //- minicore: future
438499 f$0n foo<T>() -> impl core::future::Future<Output = T>;
@@ -443,7 +504,7 @@ mod tests {
443504 ) ;
444505
445506 check_assist (
446- toggle_async_sugar ,
507+ sugar_impl_future_into_async ,
447508 r#"
448509 //- minicore: future
449510 f$0n foo<T>() -> impl core::future::Future<Output = T>
0 commit comments