@@ -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
@@ -93,8 +93,7 @@ impl<'tcx> LateLintPass<'tcx> for BlocksInConditions {
93
93
) ;
94
94
}
95
95
} else {
96
- let span = block. expr . as_ref ( ) . map_or_else ( || block. stmts [ 0 ] . span , |e| e. span ) ;
97
- if span. from_expansion ( ) || expr. span . from_expansion ( ) {
96
+ if block_is_from_expansion ( block, expr. span ) {
98
97
return ;
99
98
}
100
99
// move block higher
@@ -140,3 +139,21 @@ impl<'tcx> LateLintPass<'tcx> for BlocksInConditions {
140
139
}
141
140
}
142
141
}
142
+
143
+ fn block_is_from_expansion ( block : & Block < ' _ > , block_span : Span ) -> bool {
144
+ let block_expr_span = block. expr . map ( |e| e. span ) ;
145
+ let block_first_stmt_span = block. stmts . first ( ) . map ( |st| st. span ) ;
146
+ block_span. from_expansion ( )
147
+ || matches ! ( block_expr_span, Some ( sp) if sp. from_expansion( ) )
148
+ || matches ! ( block_first_stmt_span, Some ( sp) if sp. from_expansion( ) )
149
+ || {
150
+ // HACK: When expr and stmt overlaps, assume it was modified by some macro.
151
+ if let Some ( expr_span) = block_expr_span
152
+ && let Some ( stmt_span) = block_first_stmt_span
153
+ {
154
+ expr_span. overlaps ( stmt_span)
155
+ } else {
156
+ false
157
+ }
158
+ }
159
+ }
0 commit comments