From 1dc13b5904cde9279b76909013cd40e1661fe8eb Mon Sep 17 00:00:00 2001 From: Tomas Koutsky Date: Sun, 21 Apr 2019 17:09:30 +0300 Subject: [PATCH] Remove visit_subpats from check_pat in favor of state in EllipsisInclusiveRangePatterns --- src/librustc/lint/context.rs | 8 +++----- src/librustc/lint/mod.rs | 3 ++- src/librustc_lint/builtin.rs | 33 ++++++++++++++++++++++++++++++--- src/librustc_lint/lib.rs | 2 +- src/librustc_lint/unused.rs | 2 +- 5 files changed, 37 insertions(+), 11 deletions(-) diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 4b615345a26..34bf4adffc6 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -1164,12 +1164,10 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T> } fn visit_pat(&mut self, p: &'a ast::Pat) { - let mut visit_subpats = true; - run_early_pass!(self, check_pat, p, &mut visit_subpats); + run_early_pass!(self, check_pat, p); self.check_id(p.id); - if visit_subpats { - ast_visit::walk_pat(self, p); - } + ast_visit::walk_pat(self, p); + run_early_pass!(self, check_pat_post, p); } fn visit_expr(&mut self, e: &'a ast::Expr) { diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index 112c247d4d6..6613440ee7c 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -371,7 +371,8 @@ macro_rules! early_lint_methods { fn check_block_post(a: &ast::Block); fn check_stmt(a: &ast::Stmt); fn check_arm(a: &ast::Arm); - fn check_pat(a: &ast::Pat, b: &mut bool); // FIXME: &mut bool looks just broken + fn check_pat(a: &ast::Pat); + fn check_pat_post(a: &ast::Pat); fn check_expr(a: &ast::Expr); fn check_expr_post(a: &ast::Expr); fn check_ty(a: &ast::Ty); diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 5fde4331d47..57bc44ee30c 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -1285,10 +1285,29 @@ declare_lint! { "`...` range patterns are deprecated" } -declare_lint_pass!(EllipsisInclusiveRangePatterns => [ELLIPSIS_INCLUSIVE_RANGE_PATTERNS]); +pub struct EllipsisInclusiveRangePatterns { + /// If `Some(_)`, suppress all subsequent pattern + /// warnings for better diagnostics. + node_id: Option, +} + +impl_lint_pass!(EllipsisInclusiveRangePatterns => [ELLIPSIS_INCLUSIVE_RANGE_PATTERNS]); + +impl EllipsisInclusiveRangePatterns { + pub fn new() -> Self { + Self { + node_id: None, + } + } +} impl EarlyLintPass for EllipsisInclusiveRangePatterns { - fn check_pat(&mut self, cx: &EarlyContext<'_>, pat: &ast::Pat, visit_subpats: &mut bool) { + fn check_pat(&mut self, cx: &EarlyContext<'_>, pat: &ast::Pat) { + if self.node_id.is_some() { + // Don't recursively warn about patterns inside range endpoints. + return + } + use self::ast::{PatKind, RangeEnd, RangeSyntax::DotDotDot}; /// If `pat` is a `...` pattern, return the start and end of the range, as well as the span @@ -1311,7 +1330,7 @@ impl EarlyLintPass for EllipsisInclusiveRangePatterns { let msg = "`...` range patterns are deprecated"; let suggestion = "use `..=` for an inclusive range"; if parenthesise { - *visit_subpats = false; + self.node_id = Some(pat.id); let mut err = cx.struct_span_lint(ELLIPSIS_INCLUSIVE_RANGE_PATTERNS, pat.span, msg); err.span_suggestion( pat.span, @@ -1332,6 +1351,14 @@ impl EarlyLintPass for EllipsisInclusiveRangePatterns { }; } } + + fn check_pat_post(&mut self, _cx: &EarlyContext<'_>, pat: &ast::Pat) { + if let Some(node_id) = self.node_id { + if pat.id == node_id { + self.node_id = None + } + } + } } declare_lint! { diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 3f6348ec8dd..68ea2195619 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -94,7 +94,7 @@ macro_rules! early_lint_passes { UnusedImportBraces: UnusedImportBraces, UnsafeCode: UnsafeCode, AnonymousParameters: AnonymousParameters, - EllipsisInclusiveRangePatterns: EllipsisInclusiveRangePatterns, + EllipsisInclusiveRangePatterns: EllipsisInclusiveRangePatterns::new(), NonCamelCaseTypes: NonCamelCaseTypes, DeprecatedAttr: DeprecatedAttr::new(), ]); diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index 1182307600d..043bc62ddce 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -407,7 +407,7 @@ impl EarlyLintPass for UnusedParens { self.check_unused_parens_expr(cx, &value, msg, followed_by_block); } - fn check_pat(&mut self, cx: &EarlyContext<'_>, p: &ast::Pat, _: &mut bool) { + fn check_pat(&mut self, cx: &EarlyContext<'_>, p: &ast::Pat) { use ast::PatKind::{Paren, Range}; // The lint visitor will visit each subpattern of `p`. We do not want to lint any range // pattern no matter where it occurs in the pattern. For something like `&(a..=b)`, there