@@ -15,7 +15,7 @@ use if_chain::if_chain;
15
15
use std:: char;
16
16
use crate :: syntax:: ast:: * ;
17
17
use crate :: syntax:: source_map:: Span ;
18
- use crate :: syntax:: visit:: FnKind ;
18
+ use crate :: syntax:: visit:: { FnKind , Visitor , walk_expr } ;
19
19
use crate :: utils:: { constants, snippet, snippet_opt, span_help_and_lint, span_lint, span_lint_and_then} ;
20
20
use crate :: rustc_errors:: Applicability ;
21
21
@@ -199,6 +199,31 @@ impl LintPass for MiscEarly {
199
199
}
200
200
}
201
201
202
+ // Used to find `return` statements or equivalents e.g. `?`
203
+ struct ReturnVisitor {
204
+ found_return : bool ,
205
+ }
206
+
207
+ impl ReturnVisitor {
208
+ fn new ( ) -> Self {
209
+ Self {
210
+ found_return : false ,
211
+ }
212
+ }
213
+ }
214
+
215
+ impl < ' ast > Visitor < ' ast > for ReturnVisitor {
216
+ fn visit_expr ( & mut self , ex : & ' ast Expr ) {
217
+ if let ExprKind :: Ret ( _) = ex. node {
218
+ self . found_return = true ;
219
+ } else if let ExprKind :: Try ( _) = ex. node {
220
+ self . found_return = true ;
221
+ }
222
+
223
+ walk_expr ( self , ex)
224
+ }
225
+ }
226
+
202
227
impl EarlyLintPass for MiscEarly {
203
228
fn check_generics ( & mut self , cx : & EarlyContext < ' _ > , gen : & Generics ) {
204
229
for param in & gen. params {
@@ -311,21 +336,25 @@ impl EarlyLintPass for MiscEarly {
311
336
match expr. node {
312
337
ExprKind :: Call ( ref paren, _) => if let ExprKind :: Paren ( ref closure) = paren. node {
313
338
if let ExprKind :: Closure ( _, _, _, ref decl, ref block, _) = closure. node {
314
- span_lint_and_then (
315
- cx,
316
- REDUNDANT_CLOSURE_CALL ,
317
- expr. span ,
318
- "Try not to call a closure in the expression where it is declared." ,
319
- |db| if decl. inputs . is_empty ( ) {
320
- let hint = snippet ( cx, block. span , ".." ) . into_owned ( ) ;
321
- db. span_suggestion_with_applicability (
322
- expr. span ,
323
- "Try doing something like: " ,
324
- hint,
325
- Applicability :: MachineApplicable , // snippet
326
- ) ;
327
- } ,
328
- ) ;
339
+ let mut visitor = ReturnVisitor :: new ( ) ;
340
+ visitor. visit_expr ( block) ;
341
+ if !visitor. found_return {
342
+ span_lint_and_then (
343
+ cx,
344
+ REDUNDANT_CLOSURE_CALL ,
345
+ expr. span ,
346
+ "Try not to call a closure in the expression where it is declared." ,
347
+ |db| if decl. inputs . is_empty ( ) {
348
+ let hint = snippet ( cx, block. span , ".." ) . into_owned ( ) ;
349
+ db. span_suggestion_with_applicability (
350
+ expr. span ,
351
+ "Try doing something like: " ,
352
+ hint,
353
+ Applicability :: MachineApplicable , // snippet
354
+ ) ;
355
+ } ,
356
+ ) ;
357
+ }
329
358
}
330
359
} ,
331
360
ExprKind :: Unary ( UnOp :: Neg , ref inner) => if let ExprKind :: Unary ( UnOp :: Neg , _) = inner. node {
0 commit comments