Auto merge of #60152 - stepnivlk:visit_subpats-removal, r=varkor
Remove `visit_subpats` parameter from `check_pat`
The core idea is to keep track of current ID directly in `EllipsisInclusiveRangePatterns` struct and early return in `check_pat` based on it.
Fixes https://github.com/rust-lang/rust/issues/60043.
r? @varkor
diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs
index 4b615345..34bf4ad 100644
--- a/src/librustc/lint/context.rs
+++ b/src/librustc/lint/context.rs
@@ -1164,12 +1164,10 @@
}
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 112c247..6613440 100644
--- a/src/librustc/lint/mod.rs
+++ b/src/librustc/lint/mod.rs
@@ -371,7 +371,8 @@
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 5fde433..57bc44e 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -1285,10 +1285,29 @@
"`...` 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 @@
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 @@
};
}
}
+
+ 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 3f6348e..68ea219 100644
--- a/src/librustc_lint/lib.rs
+++ b/src/librustc_lint/lib.rs
@@ -94,7 +94,7 @@
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 1182307..043bc62 100644
--- a/src/librustc_lint/unused.rs
+++ b/src/librustc_lint/unused.rs
@@ -407,7 +407,7 @@
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