Merge #3427
3427: Fix wrong suggestion for `redundant_closure_call` r=oli-obk a=mikerite Fixes #1684 Co-authored-by: Michael Wright <mikerite@lavabit.com>
This commit is contained in:
commit
973e70cef7
@ -15,7 +15,7 @@ use if_chain::if_chain;
|
|||||||
use std::char;
|
use std::char;
|
||||||
use crate::syntax::ast::*;
|
use crate::syntax::ast::*;
|
||||||
use crate::syntax::source_map::Span;
|
use crate::syntax::source_map::Span;
|
||||||
use crate::syntax::visit::FnKind;
|
use crate::syntax::visit::{FnKind, Visitor, walk_expr};
|
||||||
use crate::utils::{constants, snippet, snippet_opt, span_help_and_lint, span_lint, span_lint_and_then};
|
use crate::utils::{constants, snippet, snippet_opt, span_help_and_lint, span_lint, span_lint_and_then};
|
||||||
use crate::rustc_errors::Applicability;
|
use crate::rustc_errors::Applicability;
|
||||||
|
|
||||||
@ -199,6 +199,31 @@ impl LintPass for MiscEarly {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Used to find `return` statements or equivalents e.g. `?`
|
||||||
|
struct ReturnVisitor {
|
||||||
|
found_return: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ReturnVisitor {
|
||||||
|
fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
found_return: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'ast> Visitor<'ast> for ReturnVisitor {
|
||||||
|
fn visit_expr(&mut self, ex: &'ast Expr) {
|
||||||
|
if let ExprKind::Ret(_) = ex.node {
|
||||||
|
self.found_return = true;
|
||||||
|
} else if let ExprKind::Try(_) = ex.node {
|
||||||
|
self.found_return = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
walk_expr(self, ex)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl EarlyLintPass for MiscEarly {
|
impl EarlyLintPass for MiscEarly {
|
||||||
fn check_generics(&mut self, cx: &EarlyContext<'_>, gen: &Generics) {
|
fn check_generics(&mut self, cx: &EarlyContext<'_>, gen: &Generics) {
|
||||||
for param in &gen.params {
|
for param in &gen.params {
|
||||||
@ -311,21 +336,25 @@ impl EarlyLintPass for MiscEarly {
|
|||||||
match expr.node {
|
match expr.node {
|
||||||
ExprKind::Call(ref paren, _) => if let ExprKind::Paren(ref closure) = paren.node {
|
ExprKind::Call(ref paren, _) => if let ExprKind::Paren(ref closure) = paren.node {
|
||||||
if let ExprKind::Closure(_, _, _, ref decl, ref block, _) = closure.node {
|
if let ExprKind::Closure(_, _, _, ref decl, ref block, _) = closure.node {
|
||||||
span_lint_and_then(
|
let mut visitor = ReturnVisitor::new();
|
||||||
cx,
|
visitor.visit_expr(block);
|
||||||
REDUNDANT_CLOSURE_CALL,
|
if !visitor.found_return {
|
||||||
expr.span,
|
span_lint_and_then(
|
||||||
"Try not to call a closure in the expression where it is declared.",
|
cx,
|
||||||
|db| if decl.inputs.is_empty() {
|
REDUNDANT_CLOSURE_CALL,
|
||||||
let hint = snippet(cx, block.span, "..").into_owned();
|
expr.span,
|
||||||
db.span_suggestion_with_applicability(
|
"Try not to call a closure in the expression where it is declared.",
|
||||||
expr.span,
|
|db| if decl.inputs.is_empty() {
|
||||||
"Try doing something like: ",
|
let hint = snippet(cx, block.span, "..").into_owned();
|
||||||
hint,
|
db.span_suggestion_with_applicability(
|
||||||
Applicability::MachineApplicable, // snippet
|
expr.span,
|
||||||
);
|
"Try doing something like: ",
|
||||||
},
|
hint,
|
||||||
);
|
Applicability::MachineApplicable, // snippet
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ExprKind::Unary(UnOp::Neg, ref inner) => if let ExprKind::Unary(UnOp::Neg, _) = inner.node {
|
ExprKind::Unary(UnOp::Neg, ref inner) => if let ExprKind::Unary(UnOp::Neg, _) = inner.node {
|
||||||
|
@ -28,4 +28,9 @@ fn main() {
|
|||||||
i = closure(3);
|
i = closure(3);
|
||||||
|
|
||||||
i = closure(4);
|
i = closure(4);
|
||||||
|
|
||||||
|
#[allow(clippy::needless_return)]
|
||||||
|
(|| return 2)();
|
||||||
|
(|| -> Option<i32> { None? })();
|
||||||
|
(|| -> Result<i32, i32> { r#try!(Err(2)) })();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user