Skip to content

Fix suggestion to add unneeded space in manual_async #6294

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions clippy_lints/src/manual_async_fn.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::utils::paths::FUTURE_FROM_GENERATOR;
use crate::utils::{match_function_call, snippet_block, snippet_opt, span_lint_and_then};
use crate::utils::{match_function_call, position_before_rarrow, snippet_block, snippet_opt, span_lint_and_then};
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir::intravisit::FnKind;
Expand Down Expand Up @@ -69,7 +69,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualAsyncFn {
|diag| {
if_chain! {
if let Some(header_snip) = snippet_opt(cx, header_span);
if let Some(ret_pos) = header_snip.rfind("->");
if let Some(ret_pos) = position_before_rarrow(header_snip.clone());
if let Some((ret_sugg, ret_snip)) = suggested_ret(cx, output);
then {
let help = format!("make the function `async` and {}", ret_sugg);
Expand Down Expand Up @@ -194,7 +194,7 @@ fn suggested_ret(cx: &LateContext<'_>, output: &Ty<'_>) -> Option<(&'static str,
},
_ => {
let sugg = "return the output of the future directly";
snippet_opt(cx, output.span).map(|snip| (sugg, format!("-> {}", snip)))
snippet_opt(cx, output.span).map(|snip| (sugg, format!(" -> {}", snip)))
},
}
}
29 changes: 8 additions & 21 deletions clippy_lints/src/unused_unit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::source_map::Span;
use rustc_span::BytePos;

use crate::utils::span_lint_and_sugg;
use crate::utils::{position_before_rarrow, span_lint_and_sugg};

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

fn lint_unneeded_unit_return(cx: &EarlyContext<'_>, ty: &ast::Ty, span: Span) {
let (ret_span, appl) = if let Ok(fn_source) = cx.sess().source_map().span_to_snippet(span.with_hi(ty.span.hi())) {
fn_source
.rfind("->")
.map_or((ty.span, Applicability::MaybeIncorrect), |rpos| {
let mut rpos = rpos;
let chars: Vec<char> = fn_source.chars().collect();
while rpos > 1 {
if let Some(c) = chars.get(rpos - 1) {
if c.is_whitespace() {
rpos -= 1;
continue;
}
}
break;
}
(
#[allow(clippy::cast_possible_truncation)]
ty.span.with_lo(BytePos(span.lo().0 + rpos as u32)),
Applicability::MachineApplicable,
)
})
position_before_rarrow(fn_source).map_or((ty.span, Applicability::MaybeIncorrect), |rpos| {
(
#[allow(clippy::cast_possible_truncation)]
ty.span.with_lo(BytePos(span.lo().0 + rpos as u32)),
Applicability::MachineApplicable,
)
})
} else {
(ty.span, Applicability::MaybeIncorrect)
};
Expand Down
29 changes: 29 additions & 0 deletions clippy_lints/src/utils/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -659,6 +659,35 @@ pub fn indent_of<T: LintContext>(cx: &T, span: Span) -> Option<usize> {
snippet_opt(cx, line_span(cx, span)).and_then(|snip| snip.find(|c: char| !c.is_whitespace()))
}

/// Returns the positon just before rarrow
///
/// ```rust,ignore
/// fn into(self) -> () {}
/// ^
/// // in case of unformatted code
/// fn into2(self)-> () {}
/// ^
/// fn into3(self) -> () {}
/// ^
/// ```
#[allow(clippy::needless_pass_by_value)]
pub fn position_before_rarrow(s: String) -> Option<usize> {
s.rfind("->").map(|rpos| {
let mut rpos = rpos;
let chars: Vec<char> = s.chars().collect();
while rpos > 1 {
if let Some(c) = chars.get(rpos - 1) {
if c.is_whitespace() {
rpos -= 1;
continue;
}
}
break;
}
rpos
})
}

/// Extends the span to the beginning of the spans line, incl. whitespaces.
///
/// ```rust,ignore
Expand Down
14 changes: 13 additions & 1 deletion tests/ui/manual_async_fn.fixed
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,19 @@ use std::future::Future;

async fn fut() -> i32 { 42 }

async fn empty_fut() {}
#[rustfmt::skip]
async fn fut2() -> i32 { 42 }

#[rustfmt::skip]
async fn fut3() -> i32 { 42 }

async fn empty_fut() {}

#[rustfmt::skip]
async fn empty_fut2() {}

#[rustfmt::skip]
async fn empty_fut3() {}

async fn core_fut() -> i32 { 42 }

Expand Down
20 changes: 20 additions & 0 deletions tests/ui/manual_async_fn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,30 @@ fn fut() -> impl Future<Output = i32> {
async { 42 }
}

#[rustfmt::skip]
fn fut2() ->impl Future<Output = i32> {
async { 42 }
}

#[rustfmt::skip]
fn fut3()-> impl Future<Output = i32> {
async { 42 }
}

fn empty_fut() -> impl Future<Output = ()> {
async {}
}

#[rustfmt::skip]
fn empty_fut2() ->impl Future<Output = ()> {
async {}
}

#[rustfmt::skip]
fn empty_fut3()-> impl Future<Output = ()> {
async {}
}

fn core_fut() -> impl core::future::Future<Output = i32> {
async move { 42 }
}
Expand Down
74 changes: 67 additions & 7 deletions tests/ui/manual_async_fn.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,82 @@ LL | fn fut() -> impl Future<Output = i32> { 42 }
| ^^^^^^

error: this function can be simplified using the `async fn` syntax
--> $DIR/manual_async_fn.rs:12:1
--> $DIR/manual_async_fn.rs:13:1
|
LL | fn fut2() ->impl Future<Output = i32> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: make the function `async` and return the output of the future directly
|
LL | async fn fut2() -> i32 {
| ^^^^^^^^^^^^^^^^^^^^^^
help: move the body of the async block to the enclosing function
|
LL | fn fut2() ->impl Future<Output = i32> { 42 }
| ^^^^^^

error: this function can be simplified using the `async fn` syntax
--> $DIR/manual_async_fn.rs:18:1
|
LL | fn fut3()-> impl Future<Output = i32> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: make the function `async` and return the output of the future directly
|
LL | async fn fut3() -> i32 {
| ^^^^^^^^^^^^^^^^^^^^^^
help: move the body of the async block to the enclosing function
|
LL | fn fut3()-> impl Future<Output = i32> { 42 }
| ^^^^^^

error: this function can be simplified using the `async fn` syntax
--> $DIR/manual_async_fn.rs:22:1
|
LL | fn empty_fut() -> impl Future<Output = ()> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: make the function `async` and remove the return type
|
LL | async fn empty_fut() {
LL | async fn empty_fut() {
| ^^^^^^^^^^^^^^^^^^^^
help: move the body of the async block to the enclosing function
|
LL | fn empty_fut() -> impl Future<Output = ()> {}
| ^^

error: this function can be simplified using the `async fn` syntax
--> $DIR/manual_async_fn.rs:16:1
--> $DIR/manual_async_fn.rs:27:1
|
LL | fn empty_fut2() ->impl Future<Output = ()> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: make the function `async` and remove the return type
|
LL | async fn empty_fut2() {
| ^^^^^^^^^^^^^^^^^^^^^
help: move the body of the async block to the enclosing function
|
LL | fn empty_fut2() ->impl Future<Output = ()> {}
| ^^

error: this function can be simplified using the `async fn` syntax
--> $DIR/manual_async_fn.rs:32:1
|
LL | fn empty_fut3()-> impl Future<Output = ()> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: make the function `async` and remove the return type
|
LL | async fn empty_fut3() {
| ^^^^^^^^^^^^^^^^^^^^^
help: move the body of the async block to the enclosing function
|
LL | fn empty_fut3()-> impl Future<Output = ()> {}
| ^^

error: this function can be simplified using the `async fn` syntax
--> $DIR/manual_async_fn.rs:36:1
|
LL | fn core_fut() -> impl core::future::Future<Output = i32> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand All @@ -45,7 +105,7 @@ LL | fn core_fut() -> impl core::future::Future<Output = i32> { 42 }
| ^^^^^^

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

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

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

error: aborting due to 6 previous errors
error: aborting due to 10 previous errors