@@ -272,7 +272,7 @@ declare_lint! {
272
272
pub struct UnusedParens ;
273
273
274
274
impl UnusedParens {
275
- fn check_unused_parens_core ( & self ,
275
+ fn check_unused_parens_expr ( & self ,
276
276
cx : & EarlyContext ,
277
277
value : & ast:: Expr ,
278
278
msg : & str ,
@@ -281,46 +281,57 @@ impl UnusedParens {
281
281
let necessary = struct_lit_needs_parens &&
282
282
parser:: contains_exterior_struct_lit ( & inner) ;
283
283
if !necessary {
284
- let span_msg = format ! ( "unnecessary parentheses around {}" , msg) ;
285
- let mut err = cx. struct_span_lint ( UNUSED_PARENS ,
286
- value. span ,
287
- & span_msg) ;
288
- // Remove exactly one pair of parentheses (rather than naïvely
289
- // stripping all paren characters)
290
- let mut ate_left_paren = false ;
291
- let mut ate_right_paren = false ;
292
- let parens_removed = pprust:: expr_to_string ( value)
293
- . trim_matches ( |c| {
294
- match c {
295
- '(' => {
296
- if ate_left_paren {
297
- false
298
- } else {
299
- ate_left_paren = true ;
300
- true
301
- }
302
- } ,
303
- ')' => {
304
- if ate_right_paren {
305
- false
306
- } else {
307
- ate_right_paren = true ;
308
- true
309
- }
310
- } ,
311
- _ => false ,
312
- }
313
- } ) . to_owned ( ) ;
314
- err. span_suggestion_short_with_applicability (
315
- value. span ,
316
- "remove these parentheses" ,
317
- parens_removed,
318
- Applicability :: MachineApplicable
319
- ) ;
320
- err. emit ( ) ;
284
+ let pattern = pprust:: expr_to_string ( value) ;
285
+ Self :: remove_outer_parens ( cx, value. span , & pattern, msg) ;
321
286
}
322
287
}
323
288
}
289
+
290
+ fn check_unused_parens_pat ( & self ,
291
+ cx : & EarlyContext ,
292
+ value : & ast:: Pat ,
293
+ msg : & str ) {
294
+ if let ast:: PatKind :: Paren ( _) = value. node {
295
+ let pattern = pprust:: pat_to_string ( value) ;
296
+ Self :: remove_outer_parens ( cx, value. span , & pattern, msg) ;
297
+ }
298
+ }
299
+
300
+ fn remove_outer_parens ( cx : & EarlyContext , span : Span , pattern : & str , msg : & str ) {
301
+ let span_msg = format ! ( "unnecessary parentheses around {}" , msg) ;
302
+ let mut err = cx. struct_span_lint ( UNUSED_PARENS , span, & span_msg) ;
303
+ let mut ate_left_paren = false ;
304
+ let mut ate_right_paren = false ;
305
+ let parens_removed = pattern
306
+ . trim_matches ( |c| {
307
+ match c {
308
+ '(' => {
309
+ if ate_left_paren {
310
+ false
311
+ } else {
312
+ ate_left_paren = true ;
313
+ true
314
+ }
315
+ } ,
316
+ ')' => {
317
+ if ate_right_paren {
318
+ false
319
+ } else {
320
+ ate_right_paren = true ;
321
+ true
322
+ }
323
+ } ,
324
+ _ => false ,
325
+ }
326
+ } ) . to_owned ( ) ;
327
+ err. span_suggestion_short_with_applicability (
328
+ span,
329
+ "remove these parentheses" ,
330
+ parens_removed,
331
+ Applicability :: MachineApplicable
332
+ ) ;
333
+ err. emit ( ) ;
334
+ }
324
335
}
325
336
326
337
impl LintPass for UnusedParens {
@@ -349,7 +360,9 @@ impl EarlyLintPass for UnusedParens {
349
360
// first "argument" is self (which sometimes needs parens)
350
361
MethodCall ( _, ref args) => ( & args[ 1 ..] , "method" ) ,
351
362
// actual catch-all arm
352
- _ => { return ; }
363
+ _ => {
364
+ return ;
365
+ }
353
366
} ;
354
367
// Don't lint if this is a nested macro expansion: otherwise, the lint could
355
368
// trigger in situations that macro authors shouldn't have to care about, e.g.,
@@ -362,18 +375,32 @@ impl EarlyLintPass for UnusedParens {
362
375
}
363
376
let msg = format ! ( "{} argument" , call_kind) ;
364
377
for arg in args_to_check {
365
- self . check_unused_parens_core ( cx, arg, & msg, false ) ;
378
+ self . check_unused_parens_expr ( cx, arg, & msg, false ) ;
366
379
}
367
380
return ;
368
381
}
369
382
} ;
370
- self . check_unused_parens_core ( cx, & value, msg, struct_lit_needs_parens) ;
383
+ self . check_unused_parens_expr ( cx, & value, msg, struct_lit_needs_parens) ;
384
+ }
385
+
386
+ fn check_pat ( & mut self , cx : & EarlyContext , p : & ast:: Pat ) {
387
+ use ast:: PatKind :: { Paren , Range } ;
388
+ // The lint visitor will visit each subpattern of `p`. We do not want to lint any range
389
+ // pattern no matter where it occurs in the pattern. For something like `&(a..=b)`, there
390
+ // is a recursive `check_pat` on `a` and `b`, but we will assume that if there are
391
+ // unnecessry parens they serve a purpose of readability.
392
+ if let Paren ( ref pat) = p. node {
393
+ match pat. node {
394
+ Range ( ..) => { }
395
+ _ => self . check_unused_parens_pat ( cx, & p, "pattern" )
396
+ }
397
+ }
371
398
}
372
399
373
400
fn check_stmt ( & mut self , cx : & EarlyContext , s : & ast:: Stmt ) {
374
401
if let ast:: StmtKind :: Local ( ref local) = s. node {
375
402
if let Some ( ref value) = local. init {
376
- self . check_unused_parens_core ( cx, & value, "assigned value" , false ) ;
403
+ self . check_unused_parens_expr ( cx, & value, "assigned value" , false ) ;
377
404
}
378
405
}
379
406
}
0 commit comments