Skip to content

Commit 4200da4

Browse files
authored
Merge pull request #18726 from Veykril/push-vyzotyqqtpqs
fix: Reduce applicability of unnecessary_async assist
2 parents 4f03dd9 + a1924e8 commit 4200da4

File tree

2 files changed

+19
-26
lines changed

2 files changed

+19
-26
lines changed

src/tools/rust-analyzer/crates/ide-assists/src/handlers/unnecessary_async.rs

+18-25
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,15 @@ use syntax::{
1212

1313
use crate::{AssistContext, Assists};
1414

15+
// FIXME: This ought to be a diagnostic lint.
16+
1517
// Assist: unnecessary_async
1618
//
1719
// Removes the `async` mark from functions which have no `.await` in their body.
1820
// Looks for calls to the functions and removes the `.await` on the call site.
1921
//
2022
// ```
21-
// pub async f$0n foo() {}
23+
// pub asy$0nc fn foo() {}
2224
// pub async fn bar() { foo().await }
2325
// ```
2426
// ->
@@ -29,15 +31,11 @@ use crate::{AssistContext, Assists};
2931
pub(crate) fn unnecessary_async(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
3032
let function: ast::Fn = ctx.find_node_at_offset()?;
3133

32-
// Do nothing if the cursor is not on the prototype. This is so that the check does not pollute
33-
// when the user asks us for assists when in the middle of the function body.
34-
// We consider the prototype to be anything that is before the body of the function.
35-
let cursor_position = ctx.offset();
36-
if cursor_position >= function.body()?.syntax().text_range().start() {
34+
// Do nothing if the cursor isn't on the async token.
35+
let async_token = function.async_token()?;
36+
if !async_token.text_range().contains_inclusive(ctx.offset()) {
3737
return None;
3838
}
39-
// Do nothing if the function isn't async.
40-
function.async_token()?;
4139
// Do nothing if the function has an `await` expression in its body.
4240
if function.body()?.syntax().descendants().find_map(ast::AwaitExpr::cast).is_some() {
4341
return None;
@@ -138,27 +136,22 @@ mod tests {
138136

139137
#[test]
140138
fn applies_on_empty_function() {
141-
check_assist(unnecessary_async, "pub async f$0n f() {}", "pub fn f() {}")
139+
check_assist(unnecessary_async, "pub asy$0nc fn f() {}", "pub fn f() {}")
142140
}
143141

144142
#[test]
145143
fn applies_and_removes_whitespace() {
146-
check_assist(unnecessary_async, "pub async f$0n f() {}", "pub fn f() {}")
147-
}
148-
149-
#[test]
150-
fn does_not_apply_on_non_async_function() {
151-
check_assist_not_applicable(unnecessary_async, "pub f$0n f() {}")
144+
check_assist(unnecessary_async, "pub async$0 fn f() {}", "pub fn f() {}")
152145
}
153146

154147
#[test]
155148
fn applies_on_function_with_a_non_await_expr() {
156-
check_assist(unnecessary_async, "pub async f$0n f() { f2() }", "pub fn f() { f2() }")
149+
check_assist(unnecessary_async, "pub asy$0nc fn f() { f2() }", "pub fn f() { f2() }")
157150
}
158151

159152
#[test]
160153
fn does_not_apply_on_function_with_an_await_expr() {
161-
check_assist_not_applicable(unnecessary_async, "pub async f$0n f() { f2().await }")
154+
check_assist_not_applicable(unnecessary_async, "pub asy$0nc fn f() { f2().await }")
162155
}
163156

164157
#[test]
@@ -167,7 +160,7 @@ mod tests {
167160
unnecessary_async,
168161
r#"
169162
pub async fn f4() { }
170-
pub async f$0n f2() { }
163+
pub asy$0nc fn f2() { }
171164
pub async fn f() { f2().await }
172165
pub async fn f3() { f2().await }"#,
173166
r#"
@@ -184,7 +177,7 @@ pub async fn f3() { f2() }"#,
184177
unnecessary_async,
185178
r#"
186179
pub async fn f4() { }
187-
mod a { pub async f$0n f2() { } }
180+
mod a { pub asy$0nc fn f2() { } }
188181
pub async fn f() { a::f2().await }
189182
pub async fn f3() { a::f2().await }"#,
190183
r#"
@@ -202,7 +195,7 @@ pub async fn f3() { a::f2() }"#,
202195
// Ensure that it is the first await on the 3rd line that is removed
203196
r#"
204197
pub async fn f() { f2().await }
205-
pub async f$0n f2() -> i32 { 1 }
198+
pub asy$0nc fn f2() -> i32 { 1 }
206199
pub async fn f3() { f4(f2().await).await }
207200
pub async fn f4(i: i32) { }"#,
208201
r#"
@@ -220,7 +213,7 @@ pub async fn f4(i: i32) { }"#,
220213
// Ensure that it is the second await on the 3rd line that is removed
221214
r#"
222215
pub async fn f() { f2().await }
223-
pub async f$0n f2(i: i32) { }
216+
pub async$0 fn f2(i: i32) { }
224217
pub async fn f3() { f2(f4().await).await }
225218
pub async fn f4() -> i32 { 1 }"#,
226219
r#"
@@ -237,7 +230,7 @@ pub async fn f4() -> i32 { 1 }"#,
237230
unnecessary_async,
238231
r#"
239232
pub struct S { }
240-
impl S { pub async f$0n f2(&self) { } }
233+
impl S { pub async$0 fn f2(&self) { } }
241234
pub async fn f(s: &S) { s.f2().await }"#,
242235
r#"
243236
pub struct S { }
@@ -250,13 +243,13 @@ pub async fn f(s: &S) { s.f2() }"#,
250243
fn does_not_apply_on_function_with_a_nested_await_expr() {
251244
check_assist_not_applicable(
252245
unnecessary_async,
253-
"async f$0n f() { if true { loop { f2().await } } }",
246+
"async$0 fn f() { if true { loop { f2().await } } }",
254247
)
255248
}
256249

257250
#[test]
258-
fn does_not_apply_when_not_on_prototype() {
259-
check_assist_not_applicable(unnecessary_async, "pub async fn f() { $0f2() }")
251+
fn does_not_apply_when_not_on_async_token() {
252+
check_assist_not_applicable(unnecessary_async, "pub async fn$0 f() { f2() }")
260253
}
261254

262255
#[test]

src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -3280,7 +3280,7 @@ fn doctest_unnecessary_async() {
32803280
check_doc_test(
32813281
"unnecessary_async",
32823282
r#####"
3283-
pub async f$0n foo() {}
3283+
pub asy$0nc fn foo() {}
32843284
pub async fn bar() { foo().await }
32853285
"#####,
32863286
r#####"

0 commit comments

Comments
 (0)