mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-27 05:23:24 +00:00
Review fixes: Assist scope, trait qualify
This commit is contained in:
parent
624f99b4b9
commit
61f8ef5d57
2 changed files with 126 additions and 45 deletions
|
@ -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!()
|
||||
}
|
||||
"#,
|
||||
|
@ -249,6 +282,23 @@ mod tests {
|
|||
fn foo() -> impl Future<Output = usize> {
|
||||
todo!()
|
||||
}
|
||||
"#,
|
||||
);
|
||||
|
||||
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!()
|
||||
}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
@ -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,10 +510,21 @@ 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;
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
@ -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;
|
||||
"#,
|
||||
|
|
|
@ -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 }
|
||||
}
|
||||
"#####,
|
||||
|
|
Loading…
Reference in a new issue