Add smarter macro check for block_in_if (fixes #528)

This commit is contained in:
Manish Goregaokar 2016-01-02 21:41:48 +05:30
parent 32cf6e32f6
commit a745efd566
3 changed files with 19 additions and 1 deletions

View file

@ -79,13 +79,18 @@ impl LateLintPass for BlockInIfCondition {
if let Some(ref ex) = block.expr { if let Some(ref ex) = block.expr {
// don't dig into the expression here, just suggest that they remove // don't dig into the expression here, just suggest that they remove
// the block // the block
if differing_macro_contexts(expr.span, ex.span) {
return;
}
span_help_and_lint(cx, BLOCK_IN_IF_CONDITION_EXPR, check.span, span_help_and_lint(cx, BLOCK_IN_IF_CONDITION_EXPR, check.span,
BRACED_EXPR_MESSAGE, BRACED_EXPR_MESSAGE,
&format!("try\nif {} {} ... ", snippet_block(cx, ex.span, ".."), &format!("try\nif {} {} ... ", snippet_block(cx, ex.span, ".."),
snippet_block(cx, then.span, ".."))); snippet_block(cx, then.span, "..")));
} }
} else { } else {
if differing_macro_contexts(expr.span, block.stmts[0].span) {
return;
}
// move block higher // move block higher
span_help_and_lint(cx, BLOCK_IN_IF_CONDITION_STMT, check.span, span_help_and_lint(cx, BLOCK_IN_IF_CONDITION_STMT, check.span,
COMPLEX_BLOCK_MESSAGE, COMPLEX_BLOCK_MESSAGE,

View file

@ -74,6 +74,10 @@ macro_rules! if_let_chain {
}; };
} }
/// Returns true if the two spans come from differing expansions (i.e. one is from a macro and one isn't)
pub fn differing_macro_contexts(sp1: Span, sp2: Span) -> bool {
sp1.expn_id != sp2.expn_id
}
/// returns true if this expn_info was expanded by any macro /// returns true if this expn_info was expanded by any macro
pub fn in_macro<T: LintContext>(cx: &T, span: Span) -> bool { pub fn in_macro<T: LintContext>(cx: &T, span: Span) -> bool {
cx.sess().codemap().with_expn_info(span.expn_id, cx.sess().codemap().with_expn_info(span.expn_id,

View file

@ -5,6 +5,15 @@
#![deny(block_in_if_condition_stmt)] #![deny(block_in_if_condition_stmt)]
#![allow(unused)] #![allow(unused)]
macro_rules! blocky {
() => {{true}}
}
fn macro_if() {
if blocky!() {
}
}
fn condition_has_block() -> i32 { fn condition_has_block() -> i32 {
if { //~ERROR in an 'if' condition, avoid complex blocks or closures with blocks; instead, move the block or closure higher and bind it with a 'let' if { //~ERROR in an 'if' condition, avoid complex blocks or closures with blocks; instead, move the block or closure higher and bind it with a 'let'