Fix implicit_return suggestion for async functions
This commit is contained in:
parent
22f8c13cf5
commit
74cf5f2fc6
5 changed files with 81 additions and 20 deletions
|
|
@ -1,5 +1,6 @@
|
|||
use clippy_utils::{
|
||||
diagnostics::span_lint_and_sugg,
|
||||
get_async_fn_body, is_async_fn,
|
||||
source::{snippet_with_applicability, snippet_with_context, walk_span_to_context},
|
||||
visitors::visit_break_exprs,
|
||||
};
|
||||
|
|
@ -219,6 +220,14 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitReturn {
|
|||
return;
|
||||
}
|
||||
|
||||
lint_implicit_returns(cx, &body.value, body.value.span.ctxt(), None);
|
||||
let expr = if is_async_fn(kind) {
|
||||
match get_async_fn_body(cx.tcx, body) {
|
||||
Some(e) => e,
|
||||
None => return,
|
||||
}
|
||||
} else {
|
||||
&body.value
|
||||
};
|
||||
lint_implicit_returns(cx, expr, expr.span.ctxt(), None);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,12 +60,12 @@ use rustc_data_structures::fx::FxHashMap;
|
|||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
|
||||
use rustc_hir::intravisit::{self, walk_expr, ErasedMap, NestedVisitorMap, Visitor};
|
||||
use rustc_hir::intravisit::{self, walk_expr, ErasedMap, FnKind, NestedVisitorMap, Visitor};
|
||||
use rustc_hir::LangItem::{ResultErr, ResultOk};
|
||||
use rustc_hir::{
|
||||
def, Arm, BindingAnnotation, Block, Body, Constness, Destination, Expr, ExprKind, FnDecl, GenericArgs, HirId, Impl,
|
||||
ImplItem, ImplItemKind, Item, ItemKind, LangItem, Local, MatchSource, Node, Param, Pat, PatKind, Path, PathSegment,
|
||||
QPath, Stmt, StmtKind, TraitItem, TraitItemKind, TraitRef, TyKind,
|
||||
ImplItem, ImplItemKind, IsAsync, Item, ItemKind, LangItem, Local, MatchSource, Node, Param, Pat, PatKind, Path,
|
||||
PathSegment, QPath, Stmt, StmtKind, TraitItem, TraitItemKind, TraitRef, TyKind,
|
||||
};
|
||||
use rustc_lint::{LateContext, Level, Lint, LintContext};
|
||||
use rustc_middle::hir::exports::Export;
|
||||
|
|
@ -1300,6 +1300,40 @@ pub fn if_sequence<'tcx>(mut expr: &'tcx Expr<'tcx>) -> (Vec<&'tcx Expr<'tcx>>,
|
|||
(conds, blocks)
|
||||
}
|
||||
|
||||
/// Checks if the given function kind is an async function.
|
||||
pub fn is_async_fn(kind: FnKind) -> bool {
|
||||
matches!(kind, FnKind::ItemFn(_, _, header, _) if header.asyncness == IsAsync::Async)
|
||||
}
|
||||
|
||||
/// Peels away all the compiler generated code surrounding the body of an async function,
|
||||
pub fn get_async_fn_body(tcx: TyCtxt<'tcx>, body: &Body<'_>) -> Option<&'tcx Expr<'tcx>> {
|
||||
if let ExprKind::Call(
|
||||
_,
|
||||
&[Expr {
|
||||
kind: ExprKind::Closure(_, _, body, _, _),
|
||||
..
|
||||
}],
|
||||
) = body.value.kind
|
||||
{
|
||||
if let ExprKind::Block(
|
||||
Block {
|
||||
stmts: [],
|
||||
expr:
|
||||
Some(Expr {
|
||||
kind: ExprKind::DropTemps(expr),
|
||||
..
|
||||
}),
|
||||
..
|
||||
},
|
||||
_,
|
||||
) = tcx.hir().body(body).value.kind
|
||||
{
|
||||
return Some(expr);
|
||||
}
|
||||
};
|
||||
None
|
||||
}
|
||||
|
||||
// Finds the `#[must_use]` attribute, if any
|
||||
pub fn must_use_attr(attrs: &[Attribute]) -> Option<&Attribute> {
|
||||
attrs.iter().find(|a| a.has_name(sym::must_use))
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
// edition:2018
|
||||
// run-rustfix
|
||||
|
||||
#![warn(clippy::implicit_return)]
|
||||
|
|
@ -122,4 +123,9 @@ fn divergent_test() -> bool {
|
|||
diverge()
|
||||
}
|
||||
|
||||
// issue #6940
|
||||
async fn foo() -> bool {
|
||||
return true
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
// edition:2018
|
||||
// run-rustfix
|
||||
|
||||
#![warn(clippy::implicit_return)]
|
||||
|
|
@ -122,4 +123,9 @@ fn divergent_test() -> bool {
|
|||
diverge()
|
||||
}
|
||||
|
||||
// issue #6940
|
||||
async fn foo() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error: missing `return` statement
|
||||
--> $DIR/implicit_return.rs:12:5
|
||||
--> $DIR/implicit_return.rs:13:5
|
||||
|
|
||||
LL | true
|
||||
| ^^^^ help: add `return` as shown: `return true`
|
||||
|
|
@ -7,85 +7,85 @@ LL | true
|
|||
= note: `-D clippy::implicit-return` implied by `-D warnings`
|
||||
|
||||
error: missing `return` statement
|
||||
--> $DIR/implicit_return.rs:16:15
|
||||
--> $DIR/implicit_return.rs:17:15
|
||||
|
|
||||
LL | if true { true } else { false }
|
||||
| ^^^^ help: add `return` as shown: `return true`
|
||||
|
||||
error: missing `return` statement
|
||||
--> $DIR/implicit_return.rs:16:29
|
||||
--> $DIR/implicit_return.rs:17:29
|
||||
|
|
||||
LL | if true { true } else { false }
|
||||
| ^^^^^ help: add `return` as shown: `return false`
|
||||
|
||||
error: missing `return` statement
|
||||
--> $DIR/implicit_return.rs:22:17
|
||||
--> $DIR/implicit_return.rs:23:17
|
||||
|
|
||||
LL | true => false,
|
||||
| ^^^^^ help: add `return` as shown: `return false`
|
||||
|
||||
error: missing `return` statement
|
||||
--> $DIR/implicit_return.rs:23:20
|
||||
--> $DIR/implicit_return.rs:24:20
|
||||
|
|
||||
LL | false => { true },
|
||||
| ^^^^ help: add `return` as shown: `return true`
|
||||
|
||||
error: missing `return` statement
|
||||
--> $DIR/implicit_return.rs:36:9
|
||||
--> $DIR/implicit_return.rs:37:9
|
||||
|
|
||||
LL | break true;
|
||||
| ^^^^^^^^^^ help: change `break` to `return` as shown: `return true`
|
||||
|
||||
error: missing `return` statement
|
||||
--> $DIR/implicit_return.rs:43:13
|
||||
--> $DIR/implicit_return.rs:44:13
|
||||
|
|
||||
LL | break true;
|
||||
| ^^^^^^^^^^ help: change `break` to `return` as shown: `return true`
|
||||
|
||||
error: missing `return` statement
|
||||
--> $DIR/implicit_return.rs:51:13
|
||||
--> $DIR/implicit_return.rs:52:13
|
||||
|
|
||||
LL | break true;
|
||||
| ^^^^^^^^^^ help: change `break` to `return` as shown: `return true`
|
||||
|
||||
error: missing `return` statement
|
||||
--> $DIR/implicit_return.rs:69:18
|
||||
--> $DIR/implicit_return.rs:70:18
|
||||
|
|
||||
LL | let _ = || { true };
|
||||
| ^^^^ help: add `return` as shown: `return true`
|
||||
|
||||
error: missing `return` statement
|
||||
--> $DIR/implicit_return.rs:70:16
|
||||
--> $DIR/implicit_return.rs:71:16
|
||||
|
|
||||
LL | let _ = || true;
|
||||
| ^^^^ help: add `return` as shown: `return true`
|
||||
|
||||
error: missing `return` statement
|
||||
--> $DIR/implicit_return.rs:78:5
|
||||
--> $DIR/implicit_return.rs:79:5
|
||||
|
|
||||
LL | format!("test {}", "test")
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add `return` as shown: `return format!("test {}", "test")`
|
||||
|
||||
error: missing `return` statement
|
||||
--> $DIR/implicit_return.rs:87:5
|
||||
--> $DIR/implicit_return.rs:88:5
|
||||
|
|
||||
LL | m!(true, false)
|
||||
| ^^^^^^^^^^^^^^^ help: add `return` as shown: `return m!(true, false)`
|
||||
|
||||
error: missing `return` statement
|
||||
--> $DIR/implicit_return.rs:93:13
|
||||
--> $DIR/implicit_return.rs:94:13
|
||||
|
|
||||
LL | break true;
|
||||
| ^^^^^^^^^^ help: change `break` to `return` as shown: `return true`
|
||||
|
||||
error: missing `return` statement
|
||||
--> $DIR/implicit_return.rs:98:17
|
||||
--> $DIR/implicit_return.rs:99:17
|
||||
|
|
||||
LL | break 'outer false;
|
||||
| ^^^^^^^^^^^^^^^^^^ help: change `break` to `return` as shown: `return false`
|
||||
|
||||
error: missing `return` statement
|
||||
--> $DIR/implicit_return.rs:113:5
|
||||
--> $DIR/implicit_return.rs:114:5
|
||||
|
|
||||
LL | / loop {
|
||||
LL | | m!(true);
|
||||
|
|
@ -99,5 +99,11 @@ LL | m!(true);
|
|||
LL | }
|
||||
|
|
||||
|
||||
error: aborting due to 15 previous errors
|
||||
error: missing `return` statement
|
||||
--> $DIR/implicit_return.rs:128:5
|
||||
|
|
||||
LL | true
|
||||
| ^^^^ help: add `return` as shown: `return true`
|
||||
|
||||
error: aborting due to 16 previous errors
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue