Skip to content

Commit e099780

Browse files
committed
Add initial impl of check_pat() for UnusedParens
This uses a copied version of `check_unused_parens_expr` that is specific to `ast::Pat`. `check_unused_parens_` could possibly be made more generic to work with any `ast::*` that has `node` and `span` fields. This also only checks for the case of parens around the wildcard pattern. It covers the case highlighted in the issue, but could check for a lot more.
1 parent 5de5281 commit e099780

File tree

1 file changed

+68
-4
lines changed

1 file changed

+68
-4
lines changed

src/librustc_lint/unused.rs

Lines changed: 68 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ declare_lint! {
264264
pub struct UnusedParens;
265265

266266
impl UnusedParens {
267-
fn check_unused_parens_core(&self,
267+
fn check_unused_parens_expr(&self,
268268
cx: &EarlyContext,
269269
value: &ast::Expr,
270270
msg: &str,
@@ -313,6 +313,56 @@ impl UnusedParens {
313313
}
314314
}
315315
}
316+
317+
fn check_unused_parens_pat(&self,
318+
cx: &EarlyContext,
319+
value: &ast::Pat,
320+
msg: &str,
321+
struct_lit_needs_parens: bool) {
322+
if let ast::PatKind::Paren(_) = value.node {
323+
// Does there need to be a check similar to `parser::contains_exterior_struct_lit`
324+
// here?
325+
if !struct_lit_needs_parens {
326+
let span_msg = format!("unnecessary parentheses around {}", msg);
327+
let mut err = cx.struct_span_lint(UNUSED_PARENS,
328+
value.span,
329+
&span_msg);
330+
// Remove exactly one pair of parentheses (rather than naïvely
331+
// stripping all paren characters)
332+
let mut ate_left_paren = false;
333+
let mut ate_right_paren = false;
334+
let parens_removed = pprust::pat_to_string(value)
335+
.trim_matches(|c| {
336+
match c {
337+
'(' => {
338+
if ate_left_paren {
339+
false
340+
} else {
341+
ate_left_paren = true;
342+
true
343+
}
344+
},
345+
')' => {
346+
if ate_right_paren {
347+
false
348+
} else {
349+
ate_right_paren = true;
350+
true
351+
}
352+
},
353+
_ => false,
354+
}
355+
}).to_owned();
356+
err.span_suggestion_short_with_applicability(
357+
value.span,
358+
"remove these parentheses",
359+
parens_removed,
360+
Applicability::MachineApplicable
361+
);
362+
err.emit();
363+
}
364+
}
365+
}
316366
}
317367

318368
impl LintPass for UnusedParens {
@@ -354,18 +404,32 @@ impl EarlyLintPass for UnusedParens {
354404
}
355405
let msg = format!("{} argument", call_kind);
356406
for arg in args_to_check {
357-
self.check_unused_parens_core(cx, arg, &msg, false);
407+
self.check_unused_parens_expr(cx, arg, &msg, false);
358408
}
359409
return;
360410
}
361411
};
362-
self.check_unused_parens_core(cx, &value, msg, struct_lit_needs_parens);
412+
self.check_unused_parens_expr(cx, &value, msg, struct_lit_needs_parens);
413+
}
414+
415+
fn check_pat(&mut self, cx: &EarlyContext, p: &ast::Pat) {
416+
use ast::PatKind::*;
417+
let (value, msg) = match p.node {
418+
Paren(ref pat) => {
419+
match pat.node {
420+
Wild => (p, "wildcard pattern"),
421+
_ => return,
422+
}
423+
}
424+
_ => return,
425+
};
426+
self.check_unused_parens_pat(cx, &value, msg, false);
363427
}
364428

365429
fn check_stmt(&mut self, cx: &EarlyContext, s: &ast::Stmt) {
366430
if let ast::StmtKind::Local(ref local) = s.node {
367431
if let Some(ref value) = local.init {
368-
self.check_unused_parens_core(cx, &value, "assigned value", false);
432+
self.check_unused_parens_expr(cx, &value, "assigned value", false);
369433
}
370434
}
371435
}

0 commit comments

Comments
 (0)