diagnostics: avoid wrong unused_parens
on x as (T) < y
This commit is contained in:
parent
91942134c6
commit
62835c9531
5 changed files with 189 additions and 1 deletions
|
@ -228,6 +228,7 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T>
|
|||
}) => self.check_id(closure_id),
|
||||
_ => {}
|
||||
}
|
||||
lint_callback!(self, check_expr_post, e);
|
||||
}
|
||||
|
||||
fn visit_generic_arg(&mut self, arg: &'a ast::GenericArg) {
|
||||
|
|
|
@ -153,6 +153,7 @@ macro_rules! early_lint_methods {
|
|||
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);
|
||||
fn check_generic_arg(a: &ast::GenericArg);
|
||||
fn check_generic_param(a: &ast::GenericParam);
|
||||
|
|
|
@ -955,11 +955,14 @@ declare_lint! {
|
|||
|
||||
pub struct UnusedParens {
|
||||
with_self_ty_parens: bool,
|
||||
/// `1 as (i32) < 2` parses to ExprKind::Lt
|
||||
/// `1 as i32 < 2` parses to i32::<2[missing angle bracket]
|
||||
parens_in_cast_in_lt: Vec<ast::NodeId>,
|
||||
}
|
||||
|
||||
impl UnusedParens {
|
||||
pub fn new() -> Self {
|
||||
Self { with_self_ty_parens: false }
|
||||
Self { with_self_ty_parens: false, parens_in_cast_in_lt: Vec::new() }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1055,6 +1058,14 @@ impl UnusedParens {
|
|||
impl EarlyLintPass for UnusedParens {
|
||||
#[inline]
|
||||
fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) {
|
||||
if let ExprKind::Binary(op, lhs, _rhs) = &e.kind &&
|
||||
(op.node == ast::BinOpKind::Lt || op.node == ast::BinOpKind::Shl) &&
|
||||
let ExprKind::Cast(_expr, ty) = &lhs.kind &&
|
||||
let ast::TyKind::Paren(_) = &ty.kind
|
||||
{
|
||||
self.parens_in_cast_in_lt.push(ty.id);
|
||||
}
|
||||
|
||||
match e.kind {
|
||||
ExprKind::Let(ref pat, _, _) | ExprKind::ForLoop(ref pat, ..) => {
|
||||
self.check_unused_parens_pat(cx, pat, false, false, (true, true));
|
||||
|
@ -1101,6 +1112,17 @@ impl EarlyLintPass for UnusedParens {
|
|||
<Self as UnusedDelimLint>::check_expr(self, cx, e)
|
||||
}
|
||||
|
||||
fn check_expr_post(&mut self, _cx: &EarlyContext<'_>, e: &ast::Expr) {
|
||||
if let ExprKind::Binary(op, lhs, _rhs) = &e.kind &&
|
||||
(op.node == ast::BinOpKind::Lt || op.node == ast::BinOpKind::Shl) &&
|
||||
let ExprKind::Cast(_expr, ty) = &lhs.kind &&
|
||||
let ast::TyKind::Paren(_) = &ty.kind
|
||||
{
|
||||
let id = self.parens_in_cast_in_lt.pop().expect("check_expr and check_expr_post must balance");
|
||||
assert_eq!(id, ty.id, "check_expr and check_expr_post is a depth-first tree traversal");
|
||||
}
|
||||
}
|
||||
|
||||
fn check_pat(&mut self, cx: &EarlyContext<'_>, p: &ast::Pat) {
|
||||
use ast::{Mutability, PatKind::*};
|
||||
let keep_space = (false, false);
|
||||
|
@ -1141,6 +1163,11 @@ impl EarlyLintPass for UnusedParens {
|
|||
}
|
||||
|
||||
fn check_ty(&mut self, cx: &EarlyContext<'_>, ty: &ast::Ty) {
|
||||
if let ast::TyKind::Paren(_) = ty.kind &&
|
||||
Some(&ty.id) == self.parens_in_cast_in_lt.last()
|
||||
{
|
||||
return;
|
||||
}
|
||||
match &ty.kind {
|
||||
ast::TyKind::Array(_, len) => {
|
||||
self.check_unused_delims_expr(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue