@@ -5,11 +5,11 @@ use clippy_utils::visitors::{for_each_expr, Descend};
5
5
use clippy_utils:: { get_parent_expr, higher} ;
6
6
use core:: ops:: ControlFlow ;
7
7
use rustc_errors:: Applicability ;
8
- use rustc_hir:: { BlockCheckMode , Expr , ExprKind , MatchSource } ;
8
+ use rustc_hir:: { Block , BlockCheckMode , Expr , ExprKind , MatchSource } ;
9
9
use rustc_lint:: { LateContext , LateLintPass , LintContext } ;
10
10
use rustc_middle:: lint:: in_external_macro;
11
11
use rustc_session:: declare_lint_pass;
12
- use rustc_span:: sym;
12
+ use rustc_span:: { sym, Span } ;
13
13
14
14
declare_clippy_lint ! {
15
15
/// ### What it does
@@ -88,8 +88,7 @@ impl<'tcx> LateLintPass<'tcx> for BlocksInConditions {
88
88
) ;
89
89
}
90
90
} else {
91
- let span = block. expr . as_ref ( ) . map_or_else ( || block. stmts [ 0 ] . span , |e| e. span ) ;
92
- if span. from_expansion ( ) || expr. span . from_expansion ( ) {
91
+ if block_is_from_expansion ( block, expr. span ) {
93
92
return ;
94
93
}
95
94
// move block higher
@@ -135,3 +134,21 @@ impl<'tcx> LateLintPass<'tcx> for BlocksInConditions {
135
134
}
136
135
}
137
136
}
137
+
138
+ fn block_is_from_expansion ( block : & Block < ' _ > , block_span : Span ) -> bool {
139
+ let block_expr_span = block. expr . map ( |e| e. span ) ;
140
+ let block_first_stmt_span = block. stmts . first ( ) . map ( |st| st. span ) ;
141
+ block_span. from_expansion ( )
142
+ || matches ! ( block_expr_span, Some ( sp) if sp. from_expansion( ) )
143
+ || matches ! ( block_first_stmt_span, Some ( sp) if sp. from_expansion( ) )
144
+ || {
145
+ // HACK: When expr and stmt overlaps, assume it was modified by some macro.
146
+ if let Some ( expr_span) = block_expr_span
147
+ && let Some ( stmt_span) = block_first_stmt_span
148
+ {
149
+ expr_span. overlaps ( stmt_span)
150
+ } else {
151
+ false
152
+ }
153
+ }
154
+ }
0 commit comments