about summary refs log tree commit diff
diff options
context:
space:
mode:
authormaxwase <max.vvase@gmail.com>2024-05-24 01:39:46 +0300
committermaxwase <max.vvase@gmail.com>2024-05-24 02:17:44 +0300
commit14dc51c1acfec5f0d01886a1422244f07d20176c (patch)
tree79e3d17217a55d035e2c4f5a37f0d32d27681f77
parent9cf35f1262c36dcd5c0f25a2875295df9e2ec856 (diff)
downloadrust-14dc51c1acfec5f0d01886a1422244f07d20176c.tar.gz
rust-14dc51c1acfec5f0d01886a1422244f07d20176c.zip
Review fixes: Assist scope, trait qualify
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/toggle_async_sugar.rs164
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs7
2 files changed, 126 insertions, 45 deletions
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/toggle_async_sugar.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/toggle_async_sugar.rs
index 356e1d50ae8..30e09648ea1 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/toggle_async_sugar.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/toggle_async_sugar.rs
@@ -1,3 +1,4 @@
+use hir::{ImportPathConfig, ModuleDef};
 use ide_db::{
     assists::{AssistId, AssistKind},
     famous_defs::FamousDefs,
@@ -11,13 +12,13 @@ use crate::{AssistContext, Assists};
 
 // Assist: sugar_impl_future_into_async
 //
-// Rewrites asynchronous function from `impl Future` to `async fn`.
+// Rewrites asynchronous function from `-> impl Future` into `async fn`.
 // This action does not touch the function body and therefore `async { 0 }`
 // block does not transform to just `0`.
 //
 // ```
 // # //- minicore: future
-// pub f$0n foo() -> impl core::future::Future<Output = usize> {
+// pub fn foo() -> impl core::future::F$0uture<Output = usize> {
 //     async { 0 }
 // }
 // ```
@@ -31,13 +32,10 @@ pub(crate) fn sugar_impl_future_into_async(
     acc: &mut Assists,
     ctx: &AssistContext<'_>,
 ) -> Option<()> {
-    let function: ast::Fn = ctx.find_node_at_offset()?;
-    if function.async_token().is_some() {
-        return None;
-    }
+    let ret_type: ast::RetType = ctx.find_node_at_offset()?;
+    let function = ret_type.syntax().parent().and_then(ast::Fn::cast)?;
 
-    let ret_type = function.ret_type()?;
-    if function.const_token().is_some() {
+    if function.async_token().is_some() || function.const_token().is_some() {
         return None;
     }
 
@@ -67,6 +65,7 @@ pub(crate) fn sugar_impl_future_into_async(
         function.syntax().text_range(),
         |builder| {
             match future_output {
+                // Empty tuple
                 ast::Type::TupleType(t) if t.fields().next().is_none() => {
                     let mut ret_type_range = ret_type.syntax().text_range();
 
@@ -103,18 +102,19 @@ pub(crate) fn sugar_impl_future_into_async(
 
 // Assist: desugar_async_into_impl_future
 //
-// Rewrites asynchronous function from `async fn` to `impl Future`.
+// Rewrites asynchronous function from `async fn` into `-> impl Future`.
 // This action does not touch the function body and therefore `0`
 // block does not transform to `async { 0 }`.
 //
 // ```
-// pub async f$0n foo() -> usize {
+// # //- minicore: future
+// pub as$0ync fn foo() -> usize {
 //     0
 // }
 // ```
 // ->
 // ```
-// pub fn foo() -> impl Future<Output = usize> {
+// pub fn foo() -> impl core::future::Future<Output = usize> {
 //     0
 // }
 // ```
@@ -122,8 +122,8 @@ pub(crate) fn desugar_async_into_impl_future(
     acc: &mut Assists,
     ctx: &AssistContext<'_>,
 ) -> Option<()> {
-    let function: ast::Fn = ctx.find_node_at_offset()?;
-    let async_token = function.async_token()?;
+    let async_token = ctx.find_token_syntax_at_offset(SyntaxKind::ASYNC_KW)?;
+    let function = async_token.parent().and_then(ast::Fn::cast)?;
 
     let rparen = function.param_list()?.r_paren_token()?;
     let return_type = match function.ret_type() {
@@ -133,6 +133,19 @@ pub(crate) fn desugar_async_into_impl_future(
         None => None,
     };
 
+    let scope = ctx.sema.scope(function.syntax())?;
+    let module = scope.module();
+    let future_trait = FamousDefs(&ctx.sema, scope.krate()).core_future_Future()?;
+    let trait_path = module.find_path(
+        ctx.db(),
+        ModuleDef::Trait(future_trait),
+        ImportPathConfig {
+            prefer_no_std: ctx.config.prefer_no_std,
+            prefer_prelude: ctx.config.prefer_prelude,
+        },
+    )?;
+    let trait_path = trait_path.display(ctx.db());
+
     acc.add(
         AssistId("desugar_async_into_impl_future", AssistKind::RefactorRewrite),
         "Convert async into `impl Future`",
@@ -148,9 +161,12 @@ pub(crate) fn desugar_async_into_impl_future(
             match return_type {
                 Some(ret_type) => builder.replace(
                     ret_type.syntax().text_range(),
-                    format!("impl Future<Output = {ret_type}>"),
+                    format!("impl {trait_path}<Output = {ret_type}>"),
+                ),
+                None => builder.insert(
+                    rparen.text_range().end(),
+                    format!(" -> impl {trait_path}<Output = ()>"),
                 ),
-                None => builder.insert(rparen.text_range().end(), " -> impl Future<Output = ()>"),
             }
         },
     )
@@ -186,7 +202,7 @@ mod tests {
             r#"
     //- minicore: future
     use core::future::Future;
-    f$0n foo() -> impl Future<Output = ()> {
+    fn foo() -> impl F$0uture<Output = ()> {
         todo!()
     }
     "#,
@@ -203,7 +219,7 @@ mod tests {
             r#"
     //- minicore: future
     use core::future::Future;
-    f$0n foo() -> impl Future<Output = usize> {
+    fn foo() -> impl F$0uture<Output = usize> {
         todo!()
     }
     "#,
@@ -223,7 +239,7 @@ mod tests {
             r#"
     //- minicore: future
     use core::future::Future;
-    async f$0n foo() {
+    as$0ync fn foo() {
         todo!()
     }
     "#,
@@ -239,8 +255,25 @@ mod tests {
             desugar_async_into_impl_future,
             r#"
     //- minicore: future
+    use core::future;
+    as$0ync fn foo() {
+        todo!()
+    }
+    "#,
+            r#"
+    use core::future;
+    fn foo() -> impl future::Future<Output = ()> {
+        todo!()
+    }
+    "#,
+        );
+
+        check_assist(
+            desugar_async_into_impl_future,
+            r#"
+    //- minicore: future
     use core::future::Future;
-    async f$0n foo() -> usize {
+    as$0ync fn foo() -> usize {
         todo!()
     }
     "#,
@@ -251,6 +284,23 @@ mod tests {
     }
     "#,
         );
+
+        check_assist(
+            desugar_async_into_impl_future,
+            r#"
+    //- minicore: future
+    use core::future::Future;
+    as$0ync fn foo() -> impl Future<Output = usize> {
+        todo!()
+    }
+    "#,
+            r#"
+    use core::future::Future;
+    fn foo() -> impl Future<Output = impl Future<Output = usize>> {
+        todo!()
+    }
+    "#,
+        );
     }
 
     #[test]
@@ -259,7 +309,7 @@ mod tests {
             sugar_impl_future_into_async,
             r#"
     //- minicore: future
-    f$0n foo() -> impl core::future::Future<Output = ()> {
+    fn foo() -> impl core::future::F$0uture<Output = ()> {
         todo!()
     }
     "#,
@@ -274,7 +324,7 @@ mod tests {
             sugar_impl_future_into_async,
             r#"
     //- minicore: future
-    f$0n foo() -> impl core::future::Future<Output = usize> {
+    fn foo() -> impl core::future::F$0uture<Output = usize> {
         todo!()
     }
     "#,
@@ -292,12 +342,12 @@ mod tests {
             desugar_async_into_impl_future,
             r#"
     //- minicore: future
-    async f$0n foo() {
+    as$0ync fn foo() {
         todo!()
     }
     "#,
             r#"
-    fn foo() -> impl Future<Output = ()> {
+    fn foo() -> impl core::future::Future<Output = ()> {
         todo!()
     }
     "#,
@@ -307,12 +357,12 @@ mod tests {
             desugar_async_into_impl_future,
             r#"
     //- minicore: future
-    async f$0n foo() -> usize {
+    as$0ync fn foo() -> usize {
         todo!()
     }
     "#,
             r#"
-    fn foo() -> impl Future<Output = usize> {
+    fn foo() -> impl core::future::Future<Output = usize> {
         todo!()
     }
     "#,
@@ -320,7 +370,7 @@ mod tests {
     }
 
     #[test]
-    fn sugar_not_applicable() {
+    fn not_applicable() {
         check_assist_not_applicable(
             sugar_impl_future_into_async,
             r#"
@@ -328,7 +378,7 @@ mod tests {
     trait Future {
         type Output;
     }
-    f$0n foo() -> impl Future<Output = ()> {
+    fn foo() -> impl F$0uture<Output = ()> {
         todo!()
     }
     "#,
@@ -341,7 +391,26 @@ mod tests {
     trait Future {
         type Output;
     }
-    f$0n foo() -> impl Future<Output = usize> {
+    fn foo() -> impl F$0uture<Output = usize> {
+        todo!()
+    }
+    "#,
+        );
+
+        check_assist_not_applicable(
+            sugar_impl_future_into_async,
+            r#"
+    //- minicore: future
+    f$0n foo() -> impl core::future::Future<Output = usize> {
+        todo!()
+    }
+    "#,
+        );
+
+        check_assist_not_applicable(
+            desugar_async_into_impl_future,
+            r#"
+    async f$0n foo() {
         todo!()
     }
     "#,
@@ -355,7 +424,7 @@ mod tests {
             r#"
     //- minicore: future
     use core::future::Future;
-    f$0n foo() -> impl Future<Output = ()>;
+    fn foo() -> impl F$0uture<Output = ()>;
     "#,
             r#"
     use core::future::Future;
@@ -368,7 +437,7 @@ mod tests {
             r#"
     //- minicore: future
     use core::future::Future;
-    f$0n foo() -> impl Future<Output = usize>;
+    fn foo() -> impl F$0uture<Output = usize>;
     "#,
             r#"
     use core::future::Future;
@@ -383,7 +452,7 @@ mod tests {
             sugar_impl_future_into_async,
             r#"
     //- minicore: future
-    f$0n foo() -> impl core::future::Future<Output = ()>;
+    fn foo() -> impl core::future::F$0uture<Output = ()>;
     "#,
             r#"
     async fn foo();
@@ -394,7 +463,7 @@ mod tests {
             sugar_impl_future_into_async,
             r#"
     //- minicore: future
-    f$0n foo() -> impl core::future::Future<Output = usize>;
+    fn foo() -> impl core::future::F$0uture<Output = usize>;
     "#,
             r#"
     async fn foo() -> usize;
@@ -408,7 +477,7 @@ mod tests {
             sugar_impl_future_into_async,
             r#"
     //- minicore: future
-    f$0n foo() -> impl core::future::Future<Output = ()> + Send + Sync;
+    fn foo() -> impl core::future::F$0uture<Output = ()> + Send + Sync;
     "#,
             r#"
     async fn foo();
@@ -419,7 +488,7 @@ mod tests {
             sugar_impl_future_into_async,
             r#"
     //- minicore: future
-    f$0n foo() -> impl core::future::Future<Output = usize> + Debug;
+    fn foo() -> impl core::future::F$0uture<Output = usize> + Debug;
     "#,
             r#"
     async fn foo() -> usize;
@@ -430,7 +499,7 @@ mod tests {
             sugar_impl_future_into_async,
             r#"
     //- minicore: future
-    f$0n foo() -> impl core::future::Future<Output = (usize)> + Debug;
+    fn foo() -> impl core::future::F$0uture<Output = (usize)> + Debug;
     "#,
             r#"
     async fn foo() -> (usize);
@@ -441,12 +510,23 @@ mod tests {
             sugar_impl_future_into_async,
             r#"
     //- minicore: future
-    f$0n foo() -> impl core::future::Future<Output = (usize, usize)> + Debug;
+    fn foo() -> impl core::future::F$0uture<Output = (usize, usize)> + Debug;
     "#,
             r#"
     async fn foo() -> (usize, usize);
     "#,
         );
+
+        check_assist(
+            sugar_impl_future_into_async,
+            r#"
+    //- minicore: future
+    fn foo() -> impl core::future::Future<Output = impl core::future::F$0uture<Output = ()> + Send>;
+    "#,
+            r#"
+    async fn foo() -> impl core::future::Future<Output = ()> + Send;
+    "#,
+        );
     }
 
     #[test]
@@ -455,7 +535,7 @@ mod tests {
             sugar_impl_future_into_async,
             r#"
     //- minicore: future
-    const f$0n foo() -> impl core::future::Future<Output = ()>;
+    const fn foo() -> impl core::future::F$0uture<Output = ()>;
     "#,
         );
 
@@ -463,7 +543,7 @@ mod tests {
             sugar_impl_future_into_async,
             r#"
             //- minicore: future
-            pub(crate) unsafe f$0n foo() -> impl core::future::Future<Output = usize>;
+            pub(crate) unsafe fn foo() -> impl core::future::F$0uture<Output = usize>;
         "#,
             r#"
             pub(crate) async unsafe fn foo() -> usize;
@@ -474,7 +554,7 @@ mod tests {
             sugar_impl_future_into_async,
             r#"
     //- minicore: future
-    unsafe f$0n foo() -> impl core::future::Future<Output = ()>;
+    unsafe fn foo() -> impl core::future::F$0uture<Output = ()>;
     "#,
             r#"
     async unsafe fn foo();
@@ -485,7 +565,7 @@ mod tests {
             sugar_impl_future_into_async,
             r#"
     //- minicore: future
-    unsafe extern "C" f$0n foo() -> impl core::future::Future<Output = ()>;
+    unsafe extern "C" fn foo() -> impl core::future::F$0uture<Output = ()>;
     "#,
             r#"
     async unsafe extern "C" fn foo();
@@ -496,7 +576,7 @@ mod tests {
             sugar_impl_future_into_async,
             r#"
     //- minicore: future
-    f$0n foo<T>() -> impl core::future::Future<Output = T>;
+    fn foo<T>() -> impl core::future::F$0uture<Output = T>;
     "#,
             r#"
     async fn foo<T>() -> T;
@@ -507,7 +587,7 @@ mod tests {
             sugar_impl_future_into_async,
             r#"
     //- minicore: future
-    f$0n foo<T>() -> impl core::future::Future<Output = T>
+    fn foo<T>() -> impl core::future::F$0uture<Output = T>
     where
         T: Sized;
     "#,
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs b/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs
index 5f187880b01..94d9e5edeff 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs
@@ -805,12 +805,13 @@ fn doctest_desugar_async_into_impl_future() {
     check_doc_test(
         "desugar_async_into_impl_future",
         r#####"
-pub async f$0n foo() -> usize {
+//- minicore: future
+pub as$0ync fn foo() -> usize {
     0
 }
 "#####,
         r#####"
-pub fn foo() -> impl Future<Output = usize> {
+pub fn foo() -> impl core::future::Future<Output = usize> {
     0
 }
 "#####,
@@ -3043,7 +3044,7 @@ fn doctest_sugar_impl_future_into_async() {
         "sugar_impl_future_into_async",
         r#####"
 //- minicore: future
-pub f$0n foo() -> impl core::future::Future<Output = usize> {
+pub fn foo() -> impl core::future::F$0uture<Output = usize> {
     async { 0 }
 }
 "#####,