@@ -96,15 +96,25 @@ fn check_is_none_or_err_and_early_return<'tcx>(cx: &LateContext<'tcx>, expr: &Ex
96
96
let receiver_str = snippet_with_applicability( cx, caller. span, ".." , & mut applicability) ;
97
97
let by_ref = !caller_ty. is_copy_modulo_regions( cx. tcx. at( caller. span) , cx. param_env) &&
98
98
!matches!( caller. kind, ExprKind :: Call ( ..) | ExprKind :: MethodCall ( ..) ) ;
99
- let mut suggestion = String :: new( ) ;
100
- if let Some ( else_inner) = r#else {
99
+ let sugg = if let Some ( else_inner) = r#else {
101
100
if eq_expr_value( cx, caller, peel_blocks( else_inner) ) {
102
- suggestion = format!( "Some({}?)" , receiver_str) ;
101
+ format!( "Some({}?)" , receiver_str)
102
+ } else {
103
+ return ;
103
104
}
104
105
} else {
105
- suggestion = format!( "{}{}?;" , receiver_str, if by_ref { ".as_ref()" } else { "" } ) ;
106
- }
107
- offer_suggestion( cx, expr, suggestion, applicability) ;
106
+ format!( "{}{}?;" , receiver_str, if by_ref { ".as_ref()" } else { "" } )
107
+ } ;
108
+
109
+ span_lint_and_sugg(
110
+ cx,
111
+ QUESTION_MARK ,
112
+ expr. span,
113
+ "this block may be rewritten with the `?` operator" ,
114
+ "replace it with" ,
115
+ sugg,
116
+ applicability,
117
+ ) ;
108
118
}
109
119
}
110
120
}
@@ -119,23 +129,27 @@ fn check_if_let_some_or_err_and_early_return<'tcx>(cx: &LateContext<'tcx>, expr:
119
129
let if_block = IfBlockType :: IfLet ( path1, caller_ty, ident. name, let_expr, if_then, if_else) ;
120
130
if ( is_early_return( sym:: Option , cx, & if_block) && path_to_local_id( peel_blocks( if_then) , bind_id) )
121
131
|| is_early_return( sym:: Result , cx, & if_block) ;
132
+ if if_else. map( |e| eq_expr_value( cx, let_expr, peel_blocks( e) ) ) . filter( |e| * e) . is_none( ) ;
122
133
then {
123
- if let Some ( else_expr) = if_else {
124
- if eq_expr_value( cx, let_expr, peel_blocks( else_expr) ) {
125
- return ;
126
- }
127
- }
128
134
let mut applicability = Applicability :: MachineApplicable ;
129
135
let receiver_str = snippet_with_applicability( cx, let_expr. span, ".." , & mut applicability) ;
130
136
let by_ref = matches!( annot, BindingAnnotation :: Ref | BindingAnnotation :: RefMut ) ;
131
137
let requires_semi = matches!( get_parent_node( cx. tcx, expr. hir_id) , Some ( Node :: Stmt ( _) ) ) ;
132
- let replacement = format!(
138
+ let sugg = format!(
133
139
"{}{}?{}" ,
134
140
receiver_str,
135
141
if by_ref { ".as_ref()" } else { "" } ,
136
142
if requires_semi { ";" } else { "" }
137
143
) ;
138
- offer_suggestion( cx, expr, replacement, applicability) ;
144
+ span_lint_and_sugg(
145
+ cx,
146
+ QUESTION_MARK ,
147
+ expr. span,
148
+ "this block may be rewritten with the `?` operator" ,
149
+ "replace it with" ,
150
+ sugg,
151
+ applicability,
152
+ ) ;
139
153
}
140
154
}
141
155
}
@@ -209,20 +223,6 @@ fn expr_return_none_or_err(
209
223
}
210
224
}
211
225
212
- fn offer_suggestion ( cx : & LateContext < ' _ > , expr : & Expr < ' _ > , suggestion : String , applicability : Applicability ) {
213
- if !suggestion. is_empty ( ) {
214
- span_lint_and_sugg (
215
- cx,
216
- QUESTION_MARK ,
217
- expr. span ,
218
- "this block may be rewritten with the `?` operator" ,
219
- "replace it with" ,
220
- suggestion,
221
- applicability,
222
- ) ;
223
- }
224
- }
225
-
226
226
impl < ' tcx > LateLintPass < ' tcx > for QuestionMark {
227
227
fn check_expr ( & mut self , cx : & LateContext < ' tcx > , expr : & ' tcx Expr < ' _ > ) {
228
228
check_is_none_or_err_and_early_return ( cx, expr) ;
0 commit comments