@@ -203,106 +203,106 @@ fn expr_return_none_or_err(
203
203
}
204
204
}
205
205
206
- impl QuestionMark {
207
- fn inside_try_block ( & self ) -> bool {
208
- self . try_block_depth_stack . last ( ) > Some ( & 0 )
209
- }
210
-
211
- /// Checks if the given expression on the given context matches the following structure:
212
- ///
213
- /// ```ignore
214
- /// if option.is_none() {
215
- /// return None;
216
- /// }
217
- /// ```
218
- ///
219
- /// ```ignore
220
- /// if result.is_err() {
221
- /// return result;
222
- /// }
223
- /// ```
224
- ///
225
- /// If it matches, it will suggest to use the question mark operator instead
226
- fn check_is_none_or_err_and_early_return < ' tcx > ( & self , cx : & LateContext < ' tcx > , expr : & Expr < ' tcx > ) {
227
- if let Some ( higher:: If { cond, then, r#else } ) = higher:: If :: hir ( expr)
228
- && !is_else_clause ( cx. tcx , expr)
229
- && let ExprKind :: MethodCall ( segment, caller, ..) = & cond. kind
230
- && let caller_ty = cx. typeck_results ( ) . expr_ty ( caller)
231
- && let if_block = IfBlockType :: IfIs ( caller, caller_ty, segment. ident . name , then)
232
- && ( is_early_return ( sym:: Option , cx, & if_block) || is_early_return ( sym:: Result , cx, & if_block) )
233
- {
234
- let mut applicability = Applicability :: MachineApplicable ;
235
- let receiver_str = snippet_with_applicability ( cx, caller. span , ".." , & mut applicability) ;
236
- let by_ref = !caller_ty. is_copy_modulo_regions ( cx. tcx , cx. param_env )
237
- && !matches ! ( caller. kind, ExprKind :: Call ( ..) | ExprKind :: MethodCall ( ..) ) ;
238
- let sugg = if let Some ( else_inner) = r#else {
239
- if eq_expr_value ( cx, caller, peel_blocks ( else_inner) ) {
240
- format ! ( "Some({receiver_str}?)" )
241
- } else {
242
- return ;
243
- }
206
+ /// Checks if the given expression on the given context matches the following structure:
207
+ ///
208
+ /// ```ignore
209
+ /// if option.is_none() {
210
+ /// return None;
211
+ /// }
212
+ /// ```
213
+ ///
214
+ /// ```ignore
215
+ /// if result.is_err() {
216
+ /// return result;
217
+ /// }
218
+ /// ```
219
+ ///
220
+ /// If it matches, it will suggest to use the question mark operator instead
221
+ fn check_is_none_or_err_and_early_return < ' tcx > ( cx : & LateContext < ' tcx > , expr : & Expr < ' tcx > ) {
222
+ if let Some ( higher:: If { cond, then, r#else } ) = higher:: If :: hir ( expr)
223
+ && !is_else_clause ( cx. tcx , expr)
224
+ && let ExprKind :: MethodCall ( segment, caller, ..) = & cond. kind
225
+ && let caller_ty = cx. typeck_results ( ) . expr_ty ( caller)
226
+ && let if_block = IfBlockType :: IfIs ( caller, caller_ty, segment. ident . name , then)
227
+ && ( is_early_return ( sym:: Option , cx, & if_block) || is_early_return ( sym:: Result , cx, & if_block) )
228
+ {
229
+ let mut applicability = Applicability :: MachineApplicable ;
230
+ let receiver_str = snippet_with_applicability ( cx, caller. span , ".." , & mut applicability) ;
231
+ let by_ref = !caller_ty. is_copy_modulo_regions ( cx. tcx , cx. param_env )
232
+ && !matches ! ( caller. kind, ExprKind :: Call ( ..) | ExprKind :: MethodCall ( ..) ) ;
233
+ let sugg = if let Some ( else_inner) = r#else {
234
+ if eq_expr_value ( cx, caller, peel_blocks ( else_inner) ) {
235
+ format ! ( "Some({receiver_str}?)" )
244
236
} else {
245
- format ! ( "{receiver_str}{}?;" , if by_ref { ".as_ref()" } else { "" } )
246
- } ;
237
+ return ;
238
+ }
239
+ } else {
240
+ format ! ( "{receiver_str}{}?;" , if by_ref { ".as_ref()" } else { "" } )
241
+ } ;
247
242
248
- span_lint_and_sugg (
249
- cx,
250
- QUESTION_MARK ,
251
- expr. span ,
252
- "this block may be rewritten with the `?` operator" ,
253
- "replace it with" ,
254
- sugg,
255
- applicability,
256
- ) ;
257
- }
243
+ span_lint_and_sugg (
244
+ cx,
245
+ QUESTION_MARK ,
246
+ expr. span ,
247
+ "this block may be rewritten with the `?` operator" ,
248
+ "replace it with" ,
249
+ sugg,
250
+ applicability,
251
+ ) ;
258
252
}
253
+ }
259
254
260
- fn check_if_let_some_or_err_and_early_return < ' tcx > ( & self , cx : & LateContext < ' tcx > , expr : & Expr < ' tcx > ) {
261
- if let Some ( higher:: IfLet {
262
- let_pat,
263
- let_expr,
264
- if_then,
265
- if_else,
266
- ..
267
- } ) = higher:: IfLet :: hir ( cx, expr)
268
- && !is_else_clause ( cx. tcx , expr)
269
- && let PatKind :: TupleStruct ( ref path1, [ field] , ddpos) = let_pat. kind
270
- && ddpos. as_opt_usize ( ) . is_none ( )
271
- && let PatKind :: Binding ( BindingAnnotation ( by_ref, _) , bind_id, ident, None ) = field. kind
272
- && let caller_ty = cx. typeck_results ( ) . expr_ty ( let_expr)
273
- && let if_block = IfBlockType :: IfLet (
274
- cx. qpath_res ( path1, let_pat. hir_id ) ,
275
- caller_ty,
276
- ident. name ,
277
- let_expr,
278
- if_then,
279
- if_else,
280
- )
281
- && ( ( is_early_return ( sym:: Option , cx, & if_block) && path_to_local_id ( peel_blocks ( if_then) , bind_id) )
282
- || is_early_return ( sym:: Result , cx, & if_block) )
283
- && if_else
284
- . map ( |e| eq_expr_value ( cx, let_expr, peel_blocks ( e) ) )
285
- . filter ( |e| * e)
286
- . is_none ( )
287
- {
288
- let mut applicability = Applicability :: MachineApplicable ;
289
- let receiver_str = snippet_with_applicability ( cx, let_expr. span , ".." , & mut applicability) ;
290
- let requires_semi = matches ! ( cx. tcx. parent_hir_node( expr. hir_id) , Node :: Stmt ( _) ) ;
291
- let sugg = format ! (
292
- "{receiver_str}{}?{}" ,
293
- if by_ref == ByRef :: Yes { ".as_ref()" } else { "" } ,
294
- if requires_semi { ";" } else { "" }
295
- ) ;
296
- span_lint_and_sugg (
297
- cx,
298
- QUESTION_MARK ,
299
- expr. span ,
300
- "this block may be rewritten with the `?` operator" ,
301
- "replace it with" ,
302
- sugg,
303
- applicability,
304
- ) ;
305
- }
255
+ fn check_if_let_some_or_err_and_early_return < ' tcx > ( cx : & LateContext < ' tcx > , expr : & Expr < ' tcx > ) {
256
+ if let Some ( higher:: IfLet {
257
+ let_pat,
258
+ let_expr,
259
+ if_then,
260
+ if_else,
261
+ ..
262
+ } ) = higher:: IfLet :: hir ( cx, expr)
263
+ && !is_else_clause ( cx. tcx , expr)
264
+ && let PatKind :: TupleStruct ( ref path1, [ field] , ddpos) = let_pat. kind
265
+ && ddpos. as_opt_usize ( ) . is_none ( )
266
+ && let PatKind :: Binding ( BindingAnnotation ( by_ref, _) , bind_id, ident, None ) = field. kind
267
+ && let caller_ty = cx. typeck_results ( ) . expr_ty ( let_expr)
268
+ && let if_block = IfBlockType :: IfLet (
269
+ cx. qpath_res ( path1, let_pat. hir_id ) ,
270
+ caller_ty,
271
+ ident. name ,
272
+ let_expr,
273
+ if_then,
274
+ if_else,
275
+ )
276
+ && ( ( is_early_return ( sym:: Option , cx, & if_block) && path_to_local_id ( peel_blocks ( if_then) , bind_id) )
277
+ || is_early_return ( sym:: Result , cx, & if_block) )
278
+ && if_else
279
+ . map ( |e| eq_expr_value ( cx, let_expr, peel_blocks ( e) ) )
280
+ . filter ( |e| * e)
281
+ . is_none ( )
282
+ {
283
+ let mut applicability = Applicability :: MachineApplicable ;
284
+ let receiver_str = snippet_with_applicability ( cx, let_expr. span , ".." , & mut applicability) ;
285
+ let requires_semi = matches ! ( cx. tcx. parent_hir_node( expr. hir_id) , Node :: Stmt ( _) ) ;
286
+ let sugg = format ! (
287
+ "{receiver_str}{}?{}" ,
288
+ if by_ref == ByRef :: Yes { ".as_ref()" } else { "" } ,
289
+ if requires_semi { ";" } else { "" }
290
+ ) ;
291
+ span_lint_and_sugg (
292
+ cx,
293
+ QUESTION_MARK ,
294
+ expr. span ,
295
+ "this block may be rewritten with the `?` operator" ,
296
+ "replace it with" ,
297
+ sugg,
298
+ applicability,
299
+ ) ;
300
+ }
301
+ }
302
+
303
+ impl QuestionMark {
304
+ fn inside_try_block ( & self ) -> bool {
305
+ self . try_block_depth_stack . last ( ) > Some ( & 0 )
306
306
}
307
307
}
308
308
@@ -328,9 +328,12 @@ impl<'tcx> LateLintPass<'tcx> for QuestionMark {
328
328
self . check_manual_let_else ( cx, stmt) ;
329
329
}
330
330
fn check_expr ( & mut self , cx : & LateContext < ' tcx > , expr : & ' tcx Expr < ' _ > ) {
331
- if !self . inside_try_block ( ) && !in_constant ( cx, expr. hir_id ) && is_lint_allowed ( cx, QUESTION_MARK_USED , expr. hir_id ) {
332
- self . check_is_none_or_err_and_early_return ( cx, expr) ;
333
- self . check_if_let_some_or_err_and_early_return ( cx, expr) ;
331
+ if !self . inside_try_block ( )
332
+ && !in_constant ( cx, expr. hir_id )
333
+ && is_lint_allowed ( cx, QUESTION_MARK_USED , expr. hir_id )
334
+ {
335
+ check_is_none_or_err_and_early_return ( cx, expr) ;
336
+ check_if_let_some_or_err_and_early_return ( cx, expr) ;
334
337
}
335
338
}
336
339
0 commit comments