use matches::matches;
use rustc::hir::intravisit::{walk_expr, NestedVisitorMap, Visitor};
use rustc::hir::*;
-use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
+use rustc::lint::{in_external_macro, LateContext, LateLintPass, LintArray, LintContext, LintPass};
use rustc::{declare_lint_pass, declare_tool_lint};
declare_clippy_lint! {
declare_lint_pass!(BlockInIfCondition => [BLOCK_IN_IF_CONDITION_EXPR, BLOCK_IN_IF_CONDITION_STMT]);
-struct ExVisitor<'a, 'tcx: 'a> {
+struct ExVisitor<'a, 'tcx> {
found_block: Option<&'tcx Expr>,
cx: &'a LateContext<'a, 'tcx>,
}
-impl<'a, 'tcx: 'a> Visitor<'tcx> for ExVisitor<'a, 'tcx> {
+impl<'a, 'tcx> Visitor<'tcx> for ExVisitor<'a, 'tcx> {
fn visit_expr(&mut self, expr: &'tcx Expr) {
if let ExprKind::Closure(_, _, eid, _, _) = expr.node {
let body = self.cx.tcx.hir().body(eid);
let ex = &body.value;
- if matches!(ex.node, ExprKind::Block(_, _)) && !in_macro(body.value.span) {
+ if matches!(ex.node, ExprKind::Block(_, _)) && !body.value.span.from_expansion() {
self.found_block = Some(ex);
return;
}
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BlockInIfCondition {
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
- if let ExprKind::If(check, then, _) = &expr.node {
+ if in_external_macro(cx.sess(), expr.span) {
+ return;
+ }
+ if let Some((check, then, _)) = higher::if_block(&expr) {
if let ExprKind::Block(block, _) = &check.node {
if block.rules == DefaultBlock {
if block.stmts.is_empty() {
if let Some(ex) = &block.expr {
// don't dig into the expression here, just suggest that they remove
// the block
- if in_macro(expr.span) || differing_macro_contexts(expr.span, ex.span) {
+ if expr.span.from_expansion() || differing_macro_contexts(expr.span, ex.span) {
return;
}
span_help_and_lint(
}
} else {
let span = block.expr.as_ref().map_or_else(|| block.stmts[0].span, |e| e.span);
- if in_macro(span) || differing_macro_contexts(expr.span, span) {
+ if span.from_expansion() || differing_macro_contexts(expr.span, span) {
return;
}
// move block higher