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
This commit is contained in:
commit
fe0a415b4b
5 changed files with 37 additions and 11 deletions
|
@ -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) {
|
fn visit_pat(&mut self, p: &'a ast::Pat) {
|
||||||
let mut visit_subpats = true;
|
run_early_pass!(self, check_pat, p);
|
||||||
run_early_pass!(self, check_pat, p, &mut visit_subpats);
|
|
||||||
self.check_id(p.id);
|
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) {
|
fn visit_expr(&mut self, e: &'a ast::Expr) {
|
||||||
|
|
|
@ -371,7 +371,8 @@ macro_rules! early_lint_methods {
|
||||||
fn check_block_post(a: &ast::Block);
|
fn check_block_post(a: &ast::Block);
|
||||||
fn check_stmt(a: &ast::Stmt);
|
fn check_stmt(a: &ast::Stmt);
|
||||||
fn check_arm(a: &ast::Arm);
|
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(a: &ast::Expr);
|
||||||
fn check_expr_post(a: &ast::Expr);
|
fn check_expr_post(a: &ast::Expr);
|
||||||
fn check_ty(a: &ast::Ty);
|
fn check_ty(a: &ast::Ty);
|
||||||
|
|
|
@ -1285,10 +1285,29 @@ declare_lint! {
|
||||||
"`...` range patterns are deprecated"
|
"`...` 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 {
|
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};
|
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
|
/// 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 msg = "`...` range patterns are deprecated";
|
||||||
let suggestion = "use `..=` for an inclusive range";
|
let suggestion = "use `..=` for an inclusive range";
|
||||||
if parenthesise {
|
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);
|
let mut err = cx.struct_span_lint(ELLIPSIS_INCLUSIVE_RANGE_PATTERNS, pat.span, msg);
|
||||||
err.span_suggestion(
|
err.span_suggestion(
|
||||||
pat.span,
|
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! {
|
declare_lint! {
|
||||||
|
|
|
@ -94,7 +94,7 @@ macro_rules! early_lint_passes {
|
||||||
UnusedImportBraces: UnusedImportBraces,
|
UnusedImportBraces: UnusedImportBraces,
|
||||||
UnsafeCode: UnsafeCode,
|
UnsafeCode: UnsafeCode,
|
||||||
AnonymousParameters: AnonymousParameters,
|
AnonymousParameters: AnonymousParameters,
|
||||||
EllipsisInclusiveRangePatterns: EllipsisInclusiveRangePatterns,
|
EllipsisInclusiveRangePatterns: EllipsisInclusiveRangePatterns::new(),
|
||||||
NonCamelCaseTypes: NonCamelCaseTypes,
|
NonCamelCaseTypes: NonCamelCaseTypes,
|
||||||
DeprecatedAttr: DeprecatedAttr::new(),
|
DeprecatedAttr: DeprecatedAttr::new(),
|
||||||
]);
|
]);
|
||||||
|
|
|
@ -407,7 +407,7 @@ impl EarlyLintPass for UnusedParens {
|
||||||
self.check_unused_parens_expr(cx, &value, msg, followed_by_block);
|
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};
|
use ast::PatKind::{Paren, Range};
|
||||||
// The lint visitor will visit each subpattern of `p`. We do not want to lint any 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
|
// pattern no matter where it occurs in the pattern. For something like `&(a..=b)`, there
|
||||||
|
|
Loading…
Add table
Reference in a new issue