generalize let_and_return for any block (closes #340)

This commit is contained in:
Georg Brandl 2015-09-20 13:57:27 +02:00
parent 56b9682624
commit 7cc291d02e
2 changed files with 16 additions and 7 deletions

View file

@ -10,7 +10,7 @@ declare_lint!(pub NEEDLESS_RETURN, Warn,
"using a return statement like `return expr;` where an expression would suffice");
declare_lint!(pub LET_AND_RETURN, Warn,
"creating a let-binding and then immediately returning it like `let x = expr; x` at \
the end of a function");
the end of a block");
#[derive(Copy, Clone)]
pub struct ReturnPass;
@ -71,11 +71,11 @@ impl ReturnPass {
if_let_chain! {
[
let Some(stmt) = block.stmts.last(),
let Some(ref retexpr) = block.expr,
let StmtDecl(ref decl, _) = stmt.node,
let DeclLocal(ref local) = decl.node,
let Some(ref initexpr) = local.init,
let PatIdent(_, Spanned { node: id, .. }, _) = local.pat.node,
let Some(ref retexpr) = block.expr,
let ExprPath(_, ref path) = retexpr.node,
match_path(path, &[&id.name.as_str()])
], {
@ -87,7 +87,7 @@ impl ReturnPass {
fn emit_let_lint(&mut self, cx: &LateContext, lint_span: Span, note_span: Span) {
if in_external_macro(cx, note_span) {return;}
span_lint(cx, LET_AND_RETURN, lint_span,
"returning the result of a let binding. \
"returning the result of a let binding from a block. \
Consider returning the expression directly.");
if cx.current_level(LET_AND_RETURN) != Level::Allow {
cx.sess().span_note(note_span,
@ -106,6 +106,9 @@ impl LateLintPass for ReturnPass {
fn check_fn(&mut self, cx: &LateContext, _: FnKind, _: &FnDecl,
block: &Block, _: Span, _: NodeId) {
self.check_block_return(cx, block);
}
fn check_block(&mut self, cx: &LateContext, block: &Block) {
self.check_let_return(cx, block);
}
}

View file

@ -1,5 +1,6 @@
#![feature(plugin)]
#![plugin(clippy)]
#![allow(unused)]
#![deny(let_and_return)]
@ -9,6 +10,15 @@ fn test() -> i32 {
x //~ERROR returning the result of a let binding
}
fn test_inner() -> i32 {
if true {
let x = 5;
x //~ERROR returning the result of a let binding
} else {
0
}
}
fn test_nowarn_1() -> i32 {
let mut x = 5;
x += 1;
@ -27,8 +37,4 @@ fn test_nowarn_3() -> (i32, i32) {
}
fn main() {
test();
test_nowarn_1();
test_nowarn_2();
test_nowarn_3();
}