Skip to content

Commit 624f99b

Browse files
committed
Review fixes: Split into 2, check tuple fields
1 parent 2657078 commit 624f99b

File tree

3 files changed

+137
-57
lines changed

3 files changed

+137
-57
lines changed

crates/ide-assists/src/handlers/toggle_async_sugar.rs

Lines changed: 111 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -9,42 +9,38 @@ use syntax::{
99

1010
use 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>

crates/ide-assists/src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,8 @@ mod handlers {
239239
change_visibility::change_visibility,
240240
convert_bool_then::convert_bool_then_to_if,
241241
convert_bool_then::convert_if_to_bool_then,
242-
toggle_async_sugar::toggle_async_sugar,
242+
toggle_async_sugar::desugar_async_into_impl_future,
243+
toggle_async_sugar::sugar_impl_future_into_async,
243244
convert_comment_block::convert_comment_block,
244245
convert_from_to_tryfrom::convert_from_to_tryfrom,
245246
convert_integer_literal::convert_integer_literal,

0 commit comments

Comments
 (0)