Make needless_return a late lint pass
This commit is contained in:
parent
f0cc006964
commit
6d18fe730e
@ -256,6 +256,7 @@ mod needless_borrow;
|
|||||||
mod needless_borrowed_ref;
|
mod needless_borrowed_ref;
|
||||||
mod needless_continue;
|
mod needless_continue;
|
||||||
mod needless_pass_by_value;
|
mod needless_pass_by_value;
|
||||||
|
mod needless_return;
|
||||||
mod needless_update;
|
mod needless_update;
|
||||||
mod neg_cmp_op_on_partial_ord;
|
mod neg_cmp_op_on_partial_ord;
|
||||||
mod neg_multiply;
|
mod neg_multiply;
|
||||||
@ -726,6 +727,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
|||||||
&needless_borrowed_ref::NEEDLESS_BORROWED_REFERENCE,
|
&needless_borrowed_ref::NEEDLESS_BORROWED_REFERENCE,
|
||||||
&needless_continue::NEEDLESS_CONTINUE,
|
&needless_continue::NEEDLESS_CONTINUE,
|
||||||
&needless_pass_by_value::NEEDLESS_PASS_BY_VALUE,
|
&needless_pass_by_value::NEEDLESS_PASS_BY_VALUE,
|
||||||
|
&needless_return::NEEDLESS_RETURN,
|
||||||
&needless_update::NEEDLESS_UPDATE,
|
&needless_update::NEEDLESS_UPDATE,
|
||||||
&neg_cmp_op_on_partial_ord::NEG_CMP_OP_ON_PARTIAL_ORD,
|
&neg_cmp_op_on_partial_ord::NEG_CMP_OP_ON_PARTIAL_ORD,
|
||||||
&neg_multiply::NEG_MULTIPLY,
|
&neg_multiply::NEG_MULTIPLY,
|
||||||
@ -769,7 +771,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
|||||||
®ex::INVALID_REGEX,
|
®ex::INVALID_REGEX,
|
||||||
®ex::TRIVIAL_REGEX,
|
®ex::TRIVIAL_REGEX,
|
||||||
&repeat_once::REPEAT_ONCE,
|
&repeat_once::REPEAT_ONCE,
|
||||||
&returns::NEEDLESS_RETURN,
|
|
||||||
&returns::UNUSED_UNIT,
|
&returns::UNUSED_UNIT,
|
||||||
&serde_api::SERDE_API_MISUSE,
|
&serde_api::SERDE_API_MISUSE,
|
||||||
&shadow::SHADOW_REUSE,
|
&shadow::SHADOW_REUSE,
|
||||||
@ -1027,6 +1028,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
|||||||
store.register_late_pass(|| box redundant_closure_call::RedundantClosureCall);
|
store.register_late_pass(|| box redundant_closure_call::RedundantClosureCall);
|
||||||
store.register_early_pass(|| box returns::Return);
|
store.register_early_pass(|| box returns::Return);
|
||||||
store.register_late_pass(|| box let_and_return::LetReturn);
|
store.register_late_pass(|| box let_and_return::LetReturn);
|
||||||
|
store.register_late_pass(|| box needless_return::NeedlessReturn);
|
||||||
store.register_early_pass(|| box collapsible_if::CollapsibleIf);
|
store.register_early_pass(|| box collapsible_if::CollapsibleIf);
|
||||||
store.register_early_pass(|| box items_after_statements::ItemsAfterStatements);
|
store.register_early_pass(|| box items_after_statements::ItemsAfterStatements);
|
||||||
store.register_early_pass(|| box precedence::Precedence);
|
store.register_early_pass(|| box precedence::Precedence);
|
||||||
@ -1381,6 +1383,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
|||||||
LintId::of(&needless_bool::BOOL_COMPARISON),
|
LintId::of(&needless_bool::BOOL_COMPARISON),
|
||||||
LintId::of(&needless_bool::NEEDLESS_BOOL),
|
LintId::of(&needless_bool::NEEDLESS_BOOL),
|
||||||
LintId::of(&needless_borrowed_ref::NEEDLESS_BORROWED_REFERENCE),
|
LintId::of(&needless_borrowed_ref::NEEDLESS_BORROWED_REFERENCE),
|
||||||
|
LintId::of(&needless_return::NEEDLESS_RETURN),
|
||||||
LintId::of(&needless_update::NEEDLESS_UPDATE),
|
LintId::of(&needless_update::NEEDLESS_UPDATE),
|
||||||
LintId::of(&neg_cmp_op_on_partial_ord::NEG_CMP_OP_ON_PARTIAL_ORD),
|
LintId::of(&neg_cmp_op_on_partial_ord::NEG_CMP_OP_ON_PARTIAL_ORD),
|
||||||
LintId::of(&neg_multiply::NEG_MULTIPLY),
|
LintId::of(&neg_multiply::NEG_MULTIPLY),
|
||||||
@ -1413,7 +1416,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
|||||||
LintId::of(®ex::INVALID_REGEX),
|
LintId::of(®ex::INVALID_REGEX),
|
||||||
LintId::of(®ex::TRIVIAL_REGEX),
|
LintId::of(®ex::TRIVIAL_REGEX),
|
||||||
LintId::of(&repeat_once::REPEAT_ONCE),
|
LintId::of(&repeat_once::REPEAT_ONCE),
|
||||||
LintId::of(&returns::NEEDLESS_RETURN),
|
|
||||||
LintId::of(&returns::UNUSED_UNIT),
|
LintId::of(&returns::UNUSED_UNIT),
|
||||||
LintId::of(&serde_api::SERDE_API_MISUSE),
|
LintId::of(&serde_api::SERDE_API_MISUSE),
|
||||||
LintId::of(&single_component_path_imports::SINGLE_COMPONENT_PATH_IMPORTS),
|
LintId::of(&single_component_path_imports::SINGLE_COMPONENT_PATH_IMPORTS),
|
||||||
@ -1543,6 +1545,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
|||||||
LintId::of(&misc_early::MIXED_CASE_HEX_LITERALS),
|
LintId::of(&misc_early::MIXED_CASE_HEX_LITERALS),
|
||||||
LintId::of(&misc_early::REDUNDANT_PATTERN),
|
LintId::of(&misc_early::REDUNDANT_PATTERN),
|
||||||
LintId::of(&mut_reference::UNNECESSARY_MUT_PASSED),
|
LintId::of(&mut_reference::UNNECESSARY_MUT_PASSED),
|
||||||
|
LintId::of(&needless_return::NEEDLESS_RETURN),
|
||||||
LintId::of(&neg_multiply::NEG_MULTIPLY),
|
LintId::of(&neg_multiply::NEG_MULTIPLY),
|
||||||
LintId::of(&new_without_default::NEW_WITHOUT_DEFAULT),
|
LintId::of(&new_without_default::NEW_WITHOUT_DEFAULT),
|
||||||
LintId::of(&non_expressive_names::JUST_UNDERSCORES_AND_DIGITS),
|
LintId::of(&non_expressive_names::JUST_UNDERSCORES_AND_DIGITS),
|
||||||
@ -1554,7 +1557,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
|||||||
LintId::of(&redundant_field_names::REDUNDANT_FIELD_NAMES),
|
LintId::of(&redundant_field_names::REDUNDANT_FIELD_NAMES),
|
||||||
LintId::of(&redundant_static_lifetimes::REDUNDANT_STATIC_LIFETIMES),
|
LintId::of(&redundant_static_lifetimes::REDUNDANT_STATIC_LIFETIMES),
|
||||||
LintId::of(®ex::TRIVIAL_REGEX),
|
LintId::of(®ex::TRIVIAL_REGEX),
|
||||||
LintId::of(&returns::NEEDLESS_RETURN),
|
|
||||||
LintId::of(&returns::UNUSED_UNIT),
|
LintId::of(&returns::UNUSED_UNIT),
|
||||||
LintId::of(&single_component_path_imports::SINGLE_COMPONENT_PATH_IMPORTS),
|
LintId::of(&single_component_path_imports::SINGLE_COMPONENT_PATH_IMPORTS),
|
||||||
LintId::of(&strings::STRING_LIT_AS_BYTES),
|
LintId::of(&strings::STRING_LIT_AS_BYTES),
|
||||||
|
166
clippy_lints/src/needless_return.rs
Normal file
166
clippy_lints/src/needless_return.rs
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
use rustc_lint::{LateLintPass, LateContext};
|
||||||
|
use rustc_ast::ast::Attribute;
|
||||||
|
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||||
|
use rustc_errors::Applicability;
|
||||||
|
use rustc_hir::intravisit::FnKind;
|
||||||
|
use rustc_span::source_map::Span;
|
||||||
|
use rustc_middle::lint::in_external_macro;
|
||||||
|
use rustc_hir::{Block, Body, Expr, ExprKind, FnDecl, HirId, MatchSource, StmtKind};
|
||||||
|
|
||||||
|
use crate::utils::{snippet_opt, span_lint_and_sugg, span_lint_and_then};
|
||||||
|
|
||||||
|
declare_clippy_lint! {
|
||||||
|
/// **What it does:** Checks for return statements at the end of a block.
|
||||||
|
///
|
||||||
|
/// **Why is this bad?** Removing the `return` and semicolon will make the code
|
||||||
|
/// more rusty.
|
||||||
|
///
|
||||||
|
/// **Known problems:** If the computation returning the value borrows a local
|
||||||
|
/// variable, removing the `return` may run afoul of the borrow checker.
|
||||||
|
///
|
||||||
|
/// **Example:**
|
||||||
|
/// ```rust
|
||||||
|
/// fn foo(x: usize) -> usize {
|
||||||
|
/// return x;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
/// simplify to
|
||||||
|
/// ```rust
|
||||||
|
/// fn foo(x: usize) -> usize {
|
||||||
|
/// x
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
pub NEEDLESS_RETURN,
|
||||||
|
style,
|
||||||
|
"using a return statement like `return expr;` where an expression would suffice"
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Eq, Copy, Clone)]
|
||||||
|
enum RetReplacement {
|
||||||
|
Empty,
|
||||||
|
Block,
|
||||||
|
}
|
||||||
|
|
||||||
|
declare_lint_pass!(NeedlessReturn => [NEEDLESS_RETURN]);
|
||||||
|
|
||||||
|
impl<'tcx> LateLintPass<'tcx> for NeedlessReturn {
|
||||||
|
fn check_fn(&mut self, cx: &LateContext<'tcx>, kind: FnKind<'tcx>, _: &'tcx FnDecl<'tcx>, body: &'tcx Body<'tcx>, _: Span, _: HirId) {
|
||||||
|
match kind {
|
||||||
|
FnKind::Closure(_) => {
|
||||||
|
check_final_expr(cx, &body.value, Some(body.value.span), RetReplacement::Empty)
|
||||||
|
}
|
||||||
|
FnKind::ItemFn(..) | FnKind::Method(..) => {
|
||||||
|
if let ExprKind::Block(ref block, _) = body.value.kind {
|
||||||
|
check_block_return(cx, block)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn attr_is_cfg(attr: &Attribute) -> bool {
|
||||||
|
attr.meta_item_list().is_some() && attr.has_name(sym!(cfg))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn check_block_return(cx: &LateContext<'_>, block: &Block<'_>) {
|
||||||
|
if let Some(expr) = block.expr {
|
||||||
|
check_final_expr(cx, expr, Some(expr.span), RetReplacement::Empty);
|
||||||
|
} else if let Some(stmt) = block.stmts.iter().last() {
|
||||||
|
match stmt.kind {
|
||||||
|
StmtKind::Expr(ref expr) | StmtKind::Semi(ref expr) => {
|
||||||
|
check_final_expr(cx, expr, Some(stmt.span), RetReplacement::Empty);
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn check_final_expr(
|
||||||
|
cx: &LateContext<'_>,
|
||||||
|
expr: &Expr<'_>,
|
||||||
|
span: Option<Span>,
|
||||||
|
replacement: RetReplacement,
|
||||||
|
) {
|
||||||
|
match expr.kind {
|
||||||
|
// simple return is always "bad"
|
||||||
|
ExprKind::Ret(ref inner) => {
|
||||||
|
|
||||||
|
// allow `#[cfg(a)] return a; #[cfg(b)] return b;`
|
||||||
|
if !expr.attrs.iter().any(attr_is_cfg) {
|
||||||
|
emit_return_lint(
|
||||||
|
cx,
|
||||||
|
span.expect("`else return` is not possible"),
|
||||||
|
inner.as_ref().map(|i| i.span),
|
||||||
|
replacement,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// a whole block? check it!
|
||||||
|
ExprKind::Block(ref block, _) => {
|
||||||
|
check_block_return(cx, block);
|
||||||
|
}
|
||||||
|
// a match expr, check all arms
|
||||||
|
// an if/if let expr, check both exprs
|
||||||
|
// note, if without else is going to be a type checking error anyways
|
||||||
|
// (except for unit type functions) so we don't match it
|
||||||
|
|
||||||
|
ExprKind::Match(_, ref arms, source) => {
|
||||||
|
match source {
|
||||||
|
MatchSource::Normal => {
|
||||||
|
for arm in arms.iter() {
|
||||||
|
check_final_expr(cx, &arm.body, Some(arm.body.span), RetReplacement::Block);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MatchSource::IfDesugar { contains_else_clause: true } | MatchSource::IfLetDesugar { contains_else_clause: true } => {
|
||||||
|
if let ExprKind::Block(ref ifblock, _) = arms[0].body.kind {
|
||||||
|
check_block_return(cx, ifblock);
|
||||||
|
}
|
||||||
|
check_final_expr(cx, arms[1].body, None, RetReplacement::Empty);
|
||||||
|
}
|
||||||
|
_ => ()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn emit_return_lint(cx: &LateContext<'_>, ret_span: Span, inner_span: Option<Span>, replacement: RetReplacement) {
|
||||||
|
match inner_span {
|
||||||
|
Some(inner_span) => {
|
||||||
|
if in_external_macro(cx.tcx.sess, inner_span) || inner_span.from_expansion() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
span_lint_and_then(cx, NEEDLESS_RETURN, ret_span, "unneeded `return` statement", |diag| {
|
||||||
|
if let Some(snippet) = snippet_opt(cx, inner_span) {
|
||||||
|
diag.span_suggestion(ret_span, "remove `return`", snippet, Applicability::MachineApplicable);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
None => match replacement {
|
||||||
|
RetReplacement::Empty => {
|
||||||
|
span_lint_and_sugg(
|
||||||
|
cx,
|
||||||
|
NEEDLESS_RETURN,
|
||||||
|
ret_span,
|
||||||
|
"unneeded `return` statement",
|
||||||
|
"remove `return`",
|
||||||
|
String::new(),
|
||||||
|
Applicability::MachineApplicable,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
RetReplacement::Block => {
|
||||||
|
span_lint_and_sugg(
|
||||||
|
cx,
|
||||||
|
NEEDLESS_RETURN,
|
||||||
|
ret_span,
|
||||||
|
"unneeded `return` statement",
|
||||||
|
"replace `return` with an empty block",
|
||||||
|
"{}".to_string(),
|
||||||
|
Applicability::MachineApplicable,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
@ -3,38 +3,11 @@ use rustc_ast::ast;
|
|||||||
use rustc_ast::visit::FnKind;
|
use rustc_ast::visit::FnKind;
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
|
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
|
||||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||||
use rustc_span::source_map::Span;
|
use rustc_span::source_map::Span;
|
||||||
use rustc_span::BytePos;
|
use rustc_span::BytePos;
|
||||||
|
|
||||||
use crate::utils::{snippet_opt, span_lint_and_sugg, span_lint_and_then};
|
use crate::utils::{span_lint_and_sugg};
|
||||||
|
|
||||||
declare_clippy_lint! {
|
|
||||||
/// **What it does:** Checks for return statements at the end of a block.
|
|
||||||
///
|
|
||||||
/// **Why is this bad?** Removing the `return` and semicolon will make the code
|
|
||||||
/// more rusty.
|
|
||||||
///
|
|
||||||
/// **Known problems:** If the computation returning the value borrows a local
|
|
||||||
/// variable, removing the `return` may run afoul of the borrow checker.
|
|
||||||
///
|
|
||||||
/// **Example:**
|
|
||||||
/// ```rust
|
|
||||||
/// fn foo(x: usize) -> usize {
|
|
||||||
/// return x;
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
/// simplify to
|
|
||||||
/// ```rust
|
|
||||||
/// fn foo(x: usize) -> usize {
|
|
||||||
/// x
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
pub NEEDLESS_RETURN,
|
|
||||||
style,
|
|
||||||
"using a return statement like `return expr;` where an expression would suffice"
|
|
||||||
}
|
|
||||||
|
|
||||||
declare_clippy_lint! {
|
declare_clippy_lint! {
|
||||||
/// **What it does:** Checks for unit (`()`) expressions that can be removed.
|
/// **What it does:** Checks for unit (`()`) expressions that can be removed.
|
||||||
@ -57,117 +30,12 @@ declare_clippy_lint! {
|
|||||||
"needless unit expression"
|
"needless unit expression"
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Copy, Clone)]
|
|
||||||
enum RetReplacement {
|
|
||||||
Empty,
|
|
||||||
Block,
|
|
||||||
}
|
|
||||||
|
|
||||||
declare_lint_pass!(Return => [NEEDLESS_RETURN, UNUSED_UNIT]);
|
declare_lint_pass!(Return => [UNUSED_UNIT]);
|
||||||
|
|
||||||
impl Return {
|
|
||||||
// Check the final stmt or expr in a block for unnecessary return.
|
|
||||||
fn check_block_return(&mut self, cx: &EarlyContext<'_>, block: &ast::Block) {
|
|
||||||
if let Some(stmt) = block.stmts.last() {
|
|
||||||
match stmt.kind {
|
|
||||||
ast::StmtKind::Expr(ref expr) | ast::StmtKind::Semi(ref expr) => {
|
|
||||||
self.check_final_expr(cx, expr, Some(stmt.span), RetReplacement::Empty);
|
|
||||||
},
|
|
||||||
_ => (),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check the final expression in a block if it's a return.
|
|
||||||
fn check_final_expr(
|
|
||||||
&mut self,
|
|
||||||
cx: &EarlyContext<'_>,
|
|
||||||
expr: &ast::Expr,
|
|
||||||
span: Option<Span>,
|
|
||||||
replacement: RetReplacement,
|
|
||||||
) {
|
|
||||||
match expr.kind {
|
|
||||||
// simple return is always "bad"
|
|
||||||
ast::ExprKind::Ret(ref inner) => {
|
|
||||||
// allow `#[cfg(a)] return a; #[cfg(b)] return b;`
|
|
||||||
if !expr.attrs.iter().any(attr_is_cfg) {
|
|
||||||
Self::emit_return_lint(
|
|
||||||
cx,
|
|
||||||
span.expect("`else return` is not possible"),
|
|
||||||
inner.as_ref().map(|i| i.span),
|
|
||||||
replacement,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// a whole block? check it!
|
|
||||||
ast::ExprKind::Block(ref block, _) => {
|
|
||||||
self.check_block_return(cx, block);
|
|
||||||
},
|
|
||||||
// an if/if let expr, check both exprs
|
|
||||||
// note, if without else is going to be a type checking error anyways
|
|
||||||
// (except for unit type functions) so we don't match it
|
|
||||||
ast::ExprKind::If(_, ref ifblock, Some(ref elsexpr)) => {
|
|
||||||
self.check_block_return(cx, ifblock);
|
|
||||||
self.check_final_expr(cx, elsexpr, None, RetReplacement::Empty);
|
|
||||||
},
|
|
||||||
// a match expr, check all arms
|
|
||||||
ast::ExprKind::Match(_, ref arms) => {
|
|
||||||
for arm in arms {
|
|
||||||
self.check_final_expr(cx, &arm.body, Some(arm.body.span), RetReplacement::Block);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
_ => (),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn emit_return_lint(cx: &EarlyContext<'_>, ret_span: Span, inner_span: Option<Span>, replacement: RetReplacement) {
|
|
||||||
match inner_span {
|
|
||||||
Some(inner_span) => {
|
|
||||||
if in_external_macro(cx.sess(), inner_span) || inner_span.from_expansion() {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
span_lint_and_then(cx, NEEDLESS_RETURN, ret_span, "unneeded `return` statement", |diag| {
|
|
||||||
if let Some(snippet) = snippet_opt(cx, inner_span) {
|
|
||||||
diag.span_suggestion(ret_span, "remove `return`", snippet, Applicability::MachineApplicable);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
None => match replacement {
|
|
||||||
RetReplacement::Empty => {
|
|
||||||
span_lint_and_sugg(
|
|
||||||
cx,
|
|
||||||
NEEDLESS_RETURN,
|
|
||||||
ret_span,
|
|
||||||
"unneeded `return` statement",
|
|
||||||
"remove `return`",
|
|
||||||
String::new(),
|
|
||||||
Applicability::MachineApplicable,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
RetReplacement::Block => {
|
|
||||||
span_lint_and_sugg(
|
|
||||||
cx,
|
|
||||||
NEEDLESS_RETURN,
|
|
||||||
ret_span,
|
|
||||||
"unneeded `return` statement",
|
|
||||||
"replace `return` with an empty block",
|
|
||||||
"{}".to_string(),
|
|
||||||
Applicability::MachineApplicable,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl EarlyLintPass for Return {
|
impl EarlyLintPass for Return {
|
||||||
fn check_fn(&mut self, cx: &EarlyContext<'_>, kind: FnKind<'_>, span: Span, _: ast::NodeId) {
|
fn check_fn(&mut self, cx: &EarlyContext<'_>, kind: FnKind<'_>, span: Span, _: ast::NodeId) {
|
||||||
match kind {
|
|
||||||
FnKind::Fn(.., Some(block)) => self.check_block_return(cx, block),
|
|
||||||
FnKind::Closure(_, body) => self.check_final_expr(cx, body, Some(body.span), RetReplacement::Empty),
|
|
||||||
FnKind::Fn(.., None) => {},
|
|
||||||
}
|
|
||||||
if_chain! {
|
if_chain! {
|
||||||
if let ast::FnRetTy::Ty(ref ty) = kind.decl().output;
|
if let ast::FnRetTy::Ty(ref ty) = kind.decl().output;
|
||||||
if let ast::TyKind::Tup(ref vals) = ty.kind;
|
if let ast::TyKind::Tup(ref vals) = ty.kind;
|
||||||
@ -234,9 +102,6 @@ impl EarlyLintPass for Return {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn attr_is_cfg(attr: &ast::Attribute) -> bool {
|
|
||||||
attr.meta_item_list().is_some() && attr.has_name(sym!(cfg))
|
|
||||||
}
|
|
||||||
|
|
||||||
// get the def site
|
// get the def site
|
||||||
#[must_use]
|
#[must_use]
|
||||||
|
@ -1534,7 +1534,7 @@ pub static ref ALL_LINTS: Vec<Lint> = vec![
|
|||||||
group: "style",
|
group: "style",
|
||||||
desc: "using a return statement like `return expr;` where an expression would suffice",
|
desc: "using a return statement like `return expr;` where an expression would suffice",
|
||||||
deprecation: None,
|
deprecation: None,
|
||||||
module: "returns",
|
module: "needless_return",
|
||||||
},
|
},
|
||||||
Lint {
|
Lint {
|
||||||
name: "needless_update",
|
name: "needless_update",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user