about summary refs log tree commit diff
diff options
context:
space:
mode:
authorTomas Koutsky <tomas@stepnivlk.net>2019-04-21 17:09:30 +0300
committerTomas Koutsky <tomas@stepnivlk.net>2019-04-23 00:17:19 +0300
commit1dc13b5904cde9279b76909013cd40e1661fe8eb (patch)
treecbb7faf6130dfec55050c6dde83cb8688400e0ca
parent6d599337fa7047307ba72786bbabe6b9c9e4daac (diff)
downloadrust-1dc13b5904cde9279b76909013cd40e1661fe8eb.tar.gz
rust-1dc13b5904cde9279b76909013cd40e1661fe8eb.zip
Remove visit_subpats from check_pat in favor of state in EllipsisInclusiveRangePatterns
-rw-r--r--src/librustc/lint/context.rs8
-rw-r--r--src/librustc/lint/mod.rs3
-rw-r--r--src/librustc_lint/builtin.rs33
-rw-r--r--src/librustc_lint/lib.rs2
-rw-r--r--src/librustc_lint/unused.rs2
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<ast::NodeId>,
+}
+
+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