@@ -5,7 +5,7 @@ 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 } ;
8
+ use rustc_hir:: { 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;
@@ -52,88 +52,89 @@ impl<'tcx> LateLintPass<'tcx> for BlocksInIfConditions {
52
52
if in_external_macro ( cx. sess ( ) , expr. span ) {
53
53
return ;
54
54
}
55
- if let Some ( higher:: If { cond, .. } ) = higher:: If :: hir ( expr) {
56
- if let ExprKind :: Block ( block, _) = & cond. kind {
57
- if block. rules == BlockCheckMode :: DefaultBlock {
58
- if block. stmts . is_empty ( ) {
59
- if let Some ( ex) = & block. expr {
60
- // don't dig into the expression here, just suggest that they remove
61
- // the block
62
- if expr. span . from_expansion ( ) || ex. span . from_expansion ( ) {
63
- return ;
64
- }
65
- let mut applicability = Applicability :: MachineApplicable ;
66
- span_lint_and_sugg (
67
- cx,
68
- BLOCKS_IN_IF_CONDITIONS ,
69
- cond. span ,
70
- BRACED_EXPR_MESSAGE ,
71
- "try" ,
72
- format ! (
73
- "{}" ,
74
- snippet_block_with_applicability(
75
- cx,
76
- ex. span,
77
- ".." ,
78
- Some ( expr. span) ,
79
- & mut applicability
80
- )
81
- ) ,
82
- applicability,
83
- ) ;
84
- }
85
- } else {
86
- let span = block. expr . as_ref ( ) . map_or_else ( || block. stmts [ 0 ] . span , |e| e. span ) ;
87
- if span. from_expansion ( ) || expr. span . from_expansion ( ) {
55
+ let Some ( ( cond, keyword) ) = higher:: If :: hir ( expr) . map ( |hif| ( hif. cond , "if" ) ) . or (
56
+ if let ExprKind :: Match ( match_ex, _, MatchSource :: Normal ) = expr. kind {
57
+ Some ( ( match_ex, "match" ) )
58
+ } else {
59
+ None
60
+ } ,
61
+ ) else {
62
+ return ;
63
+ } ;
64
+ if let ExprKind :: Block ( block, _) = & cond. kind {
65
+ if block. rules == BlockCheckMode :: DefaultBlock {
66
+ if block. stmts . is_empty ( ) {
67
+ if let Some ( ex) = & block. expr {
68
+ // don't dig into the expression here, just suggest that they remove
69
+ // the block
70
+ if expr. span . from_expansion ( ) || ex. span . from_expansion ( ) {
88
71
return ;
89
72
}
90
- // move block higher
91
73
let mut applicability = Applicability :: MachineApplicable ;
92
74
span_lint_and_sugg (
93
75
cx,
94
76
BLOCKS_IN_IF_CONDITIONS ,
95
- expr . span . with_hi ( cond. span . hi ( ) ) ,
96
- COMPLEX_BLOCK_MESSAGE ,
77
+ cond. span ,
78
+ BRACED_EXPR_MESSAGE ,
97
79
"try" ,
98
80
format ! (
99
- "let res = {}; if res " ,
81
+ "{} " ,
100
82
snippet_block_with_applicability(
101
83
cx,
102
- block . span,
84
+ ex . span,
103
85
".." ,
104
86
Some ( expr. span) ,
105
87
& mut applicability
106
- ) ,
88
+ )
107
89
) ,
108
90
applicability,
109
91
) ;
110
92
}
93
+ } else {
94
+ let span = block. expr . as_ref ( ) . map_or_else ( || block. stmts [ 0 ] . span , |e| e. span ) ;
95
+ if span. from_expansion ( ) || expr. span . from_expansion ( ) {
96
+ return ;
97
+ }
98
+ // move block higher
99
+ let mut applicability = Applicability :: MachineApplicable ;
100
+ span_lint_and_sugg (
101
+ cx,
102
+ BLOCKS_IN_IF_CONDITIONS ,
103
+ expr. span . with_hi ( cond. span . hi ( ) ) ,
104
+ COMPLEX_BLOCK_MESSAGE ,
105
+ "try" ,
106
+ format ! (
107
+ "let res = {}; {keyword} res" ,
108
+ snippet_block_with_applicability( cx, block. span, ".." , Some ( expr. span) , & mut applicability) ,
109
+ ) ,
110
+ applicability,
111
+ ) ;
111
112
}
112
- } else {
113
- let _: Option < !> = for_each_expr ( cond, |e| {
114
- if let ExprKind :: Closure ( closure) = e. kind {
115
- // do not lint if the closure is called using an iterator (see #1141)
116
- if let Some ( parent) = get_parent_expr ( cx, e)
117
- && let ExprKind :: MethodCall ( _, self_arg, _, _) = & parent. kind
118
- && let caller = cx. typeck_results ( ) . expr_ty ( self_arg)
119
- && let Some ( iter_id) = cx. tcx . get_diagnostic_item ( sym:: Iterator )
120
- && implements_trait ( cx, caller, iter_id, & [ ] )
121
- {
122
- return ControlFlow :: Continue ( Descend :: No ) ;
123
- }
113
+ }
114
+ } else {
115
+ let _: Option < !> = for_each_expr ( cond, |e| {
116
+ if let ExprKind :: Closure ( closure) = e. kind {
117
+ // do not lint if the closure is called using an iterator (see #1141)
118
+ if let Some ( parent) = get_parent_expr ( cx, e)
119
+ && let ExprKind :: MethodCall ( _, self_arg, _, _) = & parent. kind
120
+ && let caller = cx. typeck_results ( ) . expr_ty ( self_arg)
121
+ && let Some ( iter_id) = cx. tcx . get_diagnostic_item ( sym:: Iterator )
122
+ && implements_trait ( cx, caller, iter_id, & [ ] )
123
+ {
124
+ return ControlFlow :: Continue ( Descend :: No ) ;
125
+ }
124
126
125
- let body = cx. tcx . hir ( ) . body ( closure. body ) ;
126
- let ex = & body. value ;
127
- if let ExprKind :: Block ( block, _) = ex. kind {
128
- if !body. value . span . from_expansion ( ) && !block. stmts . is_empty ( ) {
129
- span_lint ( cx, BLOCKS_IN_IF_CONDITIONS , ex. span , COMPLEX_BLOCK_MESSAGE ) ;
130
- return ControlFlow :: Continue ( Descend :: No ) ;
131
- }
127
+ let body = cx. tcx . hir ( ) . body ( closure. body ) ;
128
+ let ex = & body. value ;
129
+ if let ExprKind :: Block ( block, _) = ex. kind {
130
+ if !body. value . span . from_expansion ( ) && !block. stmts . is_empty ( ) {
131
+ span_lint ( cx, BLOCKS_IN_IF_CONDITIONS , ex. span , COMPLEX_BLOCK_MESSAGE ) ;
132
+ return ControlFlow :: Continue ( Descend :: No ) ;
132
133
}
133
134
}
134
- ControlFlow :: Continue ( Descend :: Yes )
135
- } ) ;
136
- }
135
+ }
136
+ ControlFlow :: Continue ( Descend :: Yes )
137
+ } ) ;
137
138
}
138
139
}
139
140
}
0 commit comments