@@ -272,7 +272,7 @@ declare_lint! {
272272pub struct UnusedParens ;
273273
274274impl UnusedParens {
275- fn check_unused_parens_core ( & self ,
275+ fn check_unused_parens_expr ( & self ,
276276 cx : & EarlyContext ,
277277 value : & ast:: Expr ,
278278 msg : & str ,
@@ -281,46 +281,57 @@ impl UnusedParens {
281281 let necessary = struct_lit_needs_parens &&
282282 parser:: contains_exterior_struct_lit ( & inner) ;
283283 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) ;
321286 }
322287 }
323288 }
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+ }
324335}
325336
326337impl LintPass for UnusedParens {
@@ -349,7 +360,9 @@ impl EarlyLintPass for UnusedParens {
349360 // first "argument" is self (which sometimes needs parens)
350361 MethodCall ( _, ref args) => ( & args[ 1 ..] , "method" ) ,
351362 // actual catch-all arm
352- _ => { return ; }
363+ _ => {
364+ return ;
365+ }
353366 } ;
354367 // Don't lint if this is a nested macro expansion: otherwise, the lint could
355368 // trigger in situations that macro authors shouldn't have to care about, e.g.,
@@ -362,18 +375,32 @@ impl EarlyLintPass for UnusedParens {
362375 }
363376 let msg = format ! ( "{} argument" , call_kind) ;
364377 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 ) ;
366379 }
367380 return ;
368381 }
369382 } ;
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+ }
371398 }
372399
373400 fn check_stmt ( & mut self , cx : & EarlyContext , s : & ast:: Stmt ) {
374401 if let ast:: StmtKind :: Local ( ref local) = s. node {
375402 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 ) ;
377404 }
378405 }
379406 }
0 commit comments