Skip to content

Commit 2ea08e1

Browse files
committed
Auto merge of #6294 - giraffate:fix_suggestion_to_add_space_in_manual_async, r=Manishearth
Fix suggestion to add unneeded space in `manual_async` Fix a same case as #6247 changelog: Fix suggestion to add unneeded space in `manual_async`
2 parents b20d4c1 + b7892c6 commit 2ea08e1

File tree

6 files changed

+140
-32
lines changed

6 files changed

+140
-32
lines changed

clippy_lints/src/manual_async_fn.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::utils::paths::FUTURE_FROM_GENERATOR;
2-
use crate::utils::{match_function_call, snippet_block, snippet_opt, span_lint_and_then};
2+
use crate::utils::{match_function_call, position_before_rarrow, snippet_block, snippet_opt, span_lint_and_then};
33
use if_chain::if_chain;
44
use rustc_errors::Applicability;
55
use rustc_hir::intravisit::FnKind;
@@ -69,7 +69,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualAsyncFn {
6969
|diag| {
7070
if_chain! {
7171
if let Some(header_snip) = snippet_opt(cx, header_span);
72-
if let Some(ret_pos) = header_snip.rfind("->");
72+
if let Some(ret_pos) = position_before_rarrow(header_snip.clone());
7373
if let Some((ret_sugg, ret_snip)) = suggested_ret(cx, output);
7474
then {
7575
let help = format!("make the function `async` and {}", ret_sugg);
@@ -194,7 +194,7 @@ fn suggested_ret(cx: &LateContext<'_>, output: &Ty<'_>) -> Option<(&'static str,
194194
},
195195
_ => {
196196
let sugg = "return the output of the future directly";
197-
snippet_opt(cx, output.span).map(|snip| (sugg, format!("-> {}", snip)))
197+
snippet_opt(cx, output.span).map(|snip| (sugg, format!(" -> {}", snip)))
198198
},
199199
}
200200
}

clippy_lints/src/unused_unit.rs

+8-21
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use rustc_session::{declare_lint_pass, declare_tool_lint};
77
use rustc_span::source_map::Span;
88
use rustc_span::BytePos;
99

10-
use crate::utils::span_lint_and_sugg;
10+
use crate::utils::{position_before_rarrow, span_lint_and_sugg};
1111

1212
declare_clippy_lint! {
1313
/// **What it does:** Checks for unit (`()`) expressions that can be removed.
@@ -120,26 +120,13 @@ fn is_unit_expr(expr: &ast::Expr) -> bool {
120120

121121
fn lint_unneeded_unit_return(cx: &EarlyContext<'_>, ty: &ast::Ty, span: Span) {
122122
let (ret_span, appl) = if let Ok(fn_source) = cx.sess().source_map().span_to_snippet(span.with_hi(ty.span.hi())) {
123-
fn_source
124-
.rfind("->")
125-
.map_or((ty.span, Applicability::MaybeIncorrect), |rpos| {
126-
let mut rpos = rpos;
127-
let chars: Vec<char> = fn_source.chars().collect();
128-
while rpos > 1 {
129-
if let Some(c) = chars.get(rpos - 1) {
130-
if c.is_whitespace() {
131-
rpos -= 1;
132-
continue;
133-
}
134-
}
135-
break;
136-
}
137-
(
138-
#[allow(clippy::cast_possible_truncation)]
139-
ty.span.with_lo(BytePos(span.lo().0 + rpos as u32)),
140-
Applicability::MachineApplicable,
141-
)
142-
})
123+
position_before_rarrow(fn_source).map_or((ty.span, Applicability::MaybeIncorrect), |rpos| {
124+
(
125+
#[allow(clippy::cast_possible_truncation)]
126+
ty.span.with_lo(BytePos(span.lo().0 + rpos as u32)),
127+
Applicability::MachineApplicable,
128+
)
129+
})
143130
} else {
144131
(ty.span, Applicability::MaybeIncorrect)
145132
};

clippy_lints/src/utils/mod.rs

+29
Original file line numberDiff line numberDiff line change
@@ -659,6 +659,35 @@ pub fn indent_of<T: LintContext>(cx: &T, span: Span) -> Option<usize> {
659659
snippet_opt(cx, line_span(cx, span)).and_then(|snip| snip.find(|c: char| !c.is_whitespace()))
660660
}
661661

662+
/// Returns the positon just before rarrow
663+
///
664+
/// ```rust,ignore
665+
/// fn into(self) -> () {}
666+
/// ^
667+
/// // in case of unformatted code
668+
/// fn into2(self)-> () {}
669+
/// ^
670+
/// fn into3(self) -> () {}
671+
/// ^
672+
/// ```
673+
#[allow(clippy::needless_pass_by_value)]
674+
pub fn position_before_rarrow(s: String) -> Option<usize> {
675+
s.rfind("->").map(|rpos| {
676+
let mut rpos = rpos;
677+
let chars: Vec<char> = s.chars().collect();
678+
while rpos > 1 {
679+
if let Some(c) = chars.get(rpos - 1) {
680+
if c.is_whitespace() {
681+
rpos -= 1;
682+
continue;
683+
}
684+
}
685+
break;
686+
}
687+
rpos
688+
})
689+
}
690+
662691
/// Extends the span to the beginning of the spans line, incl. whitespaces.
663692
///
664693
/// ```rust,ignore

tests/ui/manual_async_fn.fixed

+13-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,19 @@ use std::future::Future;
77

88
async fn fut() -> i32 { 42 }
99

10-
async fn empty_fut() {}
10+
#[rustfmt::skip]
11+
async fn fut2() -> i32 { 42 }
12+
13+
#[rustfmt::skip]
14+
async fn fut3() -> i32 { 42 }
15+
16+
async fn empty_fut() {}
17+
18+
#[rustfmt::skip]
19+
async fn empty_fut2() {}
20+
21+
#[rustfmt::skip]
22+
async fn empty_fut3() {}
1123

1224
async fn core_fut() -> i32 { 42 }
1325

tests/ui/manual_async_fn.rs

+20
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,30 @@ fn fut() -> impl Future<Output = i32> {
99
async { 42 }
1010
}
1111

12+
#[rustfmt::skip]
13+
fn fut2() ->impl Future<Output = i32> {
14+
async { 42 }
15+
}
16+
17+
#[rustfmt::skip]
18+
fn fut3()-> impl Future<Output = i32> {
19+
async { 42 }
20+
}
21+
1222
fn empty_fut() -> impl Future<Output = ()> {
1323
async {}
1424
}
1525

26+
#[rustfmt::skip]
27+
fn empty_fut2() ->impl Future<Output = ()> {
28+
async {}
29+
}
30+
31+
#[rustfmt::skip]
32+
fn empty_fut3()-> impl Future<Output = ()> {
33+
async {}
34+
}
35+
1636
fn core_fut() -> impl core::future::Future<Output = i32> {
1737
async move { 42 }
1838
}

tests/ui/manual_async_fn.stderr

+67-7
Original file line numberDiff line numberDiff line change
@@ -15,22 +15,82 @@ LL | fn fut() -> impl Future<Output = i32> { 42 }
1515
| ^^^^^^
1616

1717
error: this function can be simplified using the `async fn` syntax
18-
--> $DIR/manual_async_fn.rs:12:1
18+
--> $DIR/manual_async_fn.rs:13:1
19+
|
20+
LL | fn fut2() ->impl Future<Output = i32> {
21+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
22+
|
23+
help: make the function `async` and return the output of the future directly
24+
|
25+
LL | async fn fut2() -> i32 {
26+
| ^^^^^^^^^^^^^^^^^^^^^^
27+
help: move the body of the async block to the enclosing function
28+
|
29+
LL | fn fut2() ->impl Future<Output = i32> { 42 }
30+
| ^^^^^^
31+
32+
error: this function can be simplified using the `async fn` syntax
33+
--> $DIR/manual_async_fn.rs:18:1
34+
|
35+
LL | fn fut3()-> impl Future<Output = i32> {
36+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
37+
|
38+
help: make the function `async` and return the output of the future directly
39+
|
40+
LL | async fn fut3() -> i32 {
41+
| ^^^^^^^^^^^^^^^^^^^^^^
42+
help: move the body of the async block to the enclosing function
43+
|
44+
LL | fn fut3()-> impl Future<Output = i32> { 42 }
45+
| ^^^^^^
46+
47+
error: this function can be simplified using the `async fn` syntax
48+
--> $DIR/manual_async_fn.rs:22:1
1949
|
2050
LL | fn empty_fut() -> impl Future<Output = ()> {
2151
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2252
|
2353
help: make the function `async` and remove the return type
2454
|
25-
LL | async fn empty_fut() {
55+
LL | async fn empty_fut() {
2656
| ^^^^^^^^^^^^^^^^^^^^
2757
help: move the body of the async block to the enclosing function
2858
|
2959
LL | fn empty_fut() -> impl Future<Output = ()> {}
3060
| ^^
3161

3262
error: this function can be simplified using the `async fn` syntax
33-
--> $DIR/manual_async_fn.rs:16:1
63+
--> $DIR/manual_async_fn.rs:27:1
64+
|
65+
LL | fn empty_fut2() ->impl Future<Output = ()> {
66+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
67+
|
68+
help: make the function `async` and remove the return type
69+
|
70+
LL | async fn empty_fut2() {
71+
| ^^^^^^^^^^^^^^^^^^^^^
72+
help: move the body of the async block to the enclosing function
73+
|
74+
LL | fn empty_fut2() ->impl Future<Output = ()> {}
75+
| ^^
76+
77+
error: this function can be simplified using the `async fn` syntax
78+
--> $DIR/manual_async_fn.rs:32:1
79+
|
80+
LL | fn empty_fut3()-> impl Future<Output = ()> {
81+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
82+
|
83+
help: make the function `async` and remove the return type
84+
|
85+
LL | async fn empty_fut3() {
86+
| ^^^^^^^^^^^^^^^^^^^^^
87+
help: move the body of the async block to the enclosing function
88+
|
89+
LL | fn empty_fut3()-> impl Future<Output = ()> {}
90+
| ^^
91+
92+
error: this function can be simplified using the `async fn` syntax
93+
--> $DIR/manual_async_fn.rs:36:1
3494
|
3595
LL | fn core_fut() -> impl core::future::Future<Output = i32> {
3696
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -45,7 +105,7 @@ LL | fn core_fut() -> impl core::future::Future<Output = i32> { 42 }
45105
| ^^^^^^
46106

47107
error: this function can be simplified using the `async fn` syntax
48-
--> $DIR/manual_async_fn.rs:38:5
108+
--> $DIR/manual_async_fn.rs:58:5
49109
|
50110
LL | fn inh_fut() -> impl Future<Output = i32> {
51111
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -65,7 +125,7 @@ LL | let c = 21;
65125
...
66126

67127
error: this function can be simplified using the `async fn` syntax
68-
--> $DIR/manual_async_fn.rs:73:1
128+
--> $DIR/manual_async_fn.rs:93:1
69129
|
70130
LL | fn elided(_: &i32) -> impl Future<Output = i32> + '_ {
71131
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -80,7 +140,7 @@ LL | fn elided(_: &i32) -> impl Future<Output = i32> + '_ { 42 }
80140
| ^^^^^^
81141

82142
error: this function can be simplified using the `async fn` syntax
83-
--> $DIR/manual_async_fn.rs:82:1
143+
--> $DIR/manual_async_fn.rs:102:1
84144
|
85145
LL | fn explicit<'a, 'b>(_: &'a i32, _: &'b i32) -> impl Future<Output = i32> + 'a + 'b {
86146
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -94,5 +154,5 @@ help: move the body of the async block to the enclosing function
94154
LL | fn explicit<'a, 'b>(_: &'a i32, _: &'b i32) -> impl Future<Output = i32> + 'a + 'b { 42 }
95155
| ^^^^^^
96156

97-
error: aborting due to 6 previous errors
157+
error: aborting due to 10 previous errors
98158

0 commit comments

Comments
 (0)