mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-01 02:14:20 +00:00
Eliminate magic numbers from expression precedence
This commit is contained in:
parent
539c863eaf
commit
7ced18f329
@ -39,9 +39,7 @@ pub use crate::format::*;
|
||||
use crate::ptr::P;
|
||||
use crate::token::{self, CommentKind, Delimiter};
|
||||
use crate::tokenstream::{DelimSpan, LazyAttrTokenStream, TokenStream};
|
||||
use crate::util::parser::{
|
||||
AssocOp, PREC_CLOSURE, PREC_JUMP, PREC_PREFIX, PREC_RANGE, PREC_UNAMBIGUOUS,
|
||||
};
|
||||
use crate::util::parser::{AssocOp, ExprPrecedence};
|
||||
|
||||
/// A "Label" is an identifier of some point in sources,
|
||||
/// e.g. in the following code:
|
||||
@ -1317,29 +1315,29 @@ impl Expr {
|
||||
Some(P(Ty { kind, id: self.id, span: self.span, tokens: None }))
|
||||
}
|
||||
|
||||
pub fn precedence(&self) -> i8 {
|
||||
pub fn precedence(&self) -> ExprPrecedence {
|
||||
match self.kind {
|
||||
ExprKind::Closure(..) => PREC_CLOSURE,
|
||||
ExprKind::Closure(..) => ExprPrecedence::Closure,
|
||||
|
||||
ExprKind::Break(..)
|
||||
| ExprKind::Continue(..)
|
||||
| ExprKind::Ret(..)
|
||||
| ExprKind::Yield(..)
|
||||
| ExprKind::Yeet(..)
|
||||
| ExprKind::Become(..) => PREC_JUMP,
|
||||
| ExprKind::Become(..) => ExprPrecedence::Jump,
|
||||
|
||||
// `Range` claims to have higher precedence than `Assign`, but `x .. x = x` fails to
|
||||
// parse, instead of parsing as `(x .. x) = x`. Giving `Range` a lower precedence
|
||||
// ensures that `pprust` will add parentheses in the right places to get the desired
|
||||
// parse.
|
||||
ExprKind::Range(..) => PREC_RANGE,
|
||||
ExprKind::Range(..) => ExprPrecedence::Range,
|
||||
|
||||
// Binop-like expr kinds, handled by `AssocOp`.
|
||||
ExprKind::Binary(op, ..) => AssocOp::from_ast_binop(op.node).precedence() as i8,
|
||||
ExprKind::Cast(..) => AssocOp::As.precedence() as i8,
|
||||
ExprKind::Binary(op, ..) => AssocOp::from_ast_binop(op.node).precedence(),
|
||||
ExprKind::Cast(..) => ExprPrecedence::Cast,
|
||||
|
||||
ExprKind::Assign(..) |
|
||||
ExprKind::AssignOp(..) => AssocOp::Assign.precedence() as i8,
|
||||
ExprKind::AssignOp(..) => ExprPrecedence::Assign,
|
||||
|
||||
// Unary, prefix
|
||||
ExprKind::AddrOf(..)
|
||||
@ -1348,7 +1346,7 @@ impl Expr {
|
||||
// need parens sometimes. E.g. we can print `(let _ = a) && b` as `let _ = a && b`
|
||||
// but we need to print `(let _ = a) < b` as-is with parens.
|
||||
| ExprKind::Let(..)
|
||||
| ExprKind::Unary(..) => PREC_PREFIX,
|
||||
| ExprKind::Unary(..) => ExprPrecedence::Prefix,
|
||||
|
||||
// Never need parens
|
||||
ExprKind::Array(_)
|
||||
@ -1381,7 +1379,7 @@ impl Expr {
|
||||
| ExprKind::Underscore
|
||||
| ExprKind::While(..)
|
||||
| ExprKind::Err(_)
|
||||
| ExprKind::Dummy => PREC_UNAMBIGUOUS,
|
||||
| ExprKind::Dummy => ExprPrecedence::Unambiguous,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -128,21 +128,21 @@ impl AssocOp {
|
||||
}
|
||||
|
||||
/// Gets the precedence of this operator
|
||||
pub fn precedence(&self) -> usize {
|
||||
pub fn precedence(&self) -> ExprPrecedence {
|
||||
use AssocOp::*;
|
||||
match *self {
|
||||
As => 14,
|
||||
Multiply | Divide | Modulus => 13,
|
||||
Add | Subtract => 12,
|
||||
ShiftLeft | ShiftRight => 11,
|
||||
BitAnd => 10,
|
||||
BitXor => 9,
|
||||
BitOr => 8,
|
||||
Less | Greater | LessEqual | GreaterEqual | Equal | NotEqual => 7,
|
||||
LAnd => 6,
|
||||
LOr => 5,
|
||||
DotDot | DotDotEq => 4,
|
||||
Assign | AssignOp(_) => 2,
|
||||
As => ExprPrecedence::Cast,
|
||||
Multiply | Divide | Modulus => ExprPrecedence::Product,
|
||||
Add | Subtract => ExprPrecedence::Sum,
|
||||
ShiftLeft | ShiftRight => ExprPrecedence::Shift,
|
||||
BitAnd => ExprPrecedence::BitAnd,
|
||||
BitXor => ExprPrecedence::BitXor,
|
||||
BitOr => ExprPrecedence::BitOr,
|
||||
Less | Greater | LessEqual | GreaterEqual | Equal | NotEqual => ExprPrecedence::Compare,
|
||||
LAnd => ExprPrecedence::LAnd,
|
||||
LOr => ExprPrecedence::LOr,
|
||||
DotDot | DotDotEq => ExprPrecedence::Range,
|
||||
Assign | AssignOp(_) => ExprPrecedence::Assign,
|
||||
}
|
||||
}
|
||||
|
||||
@ -229,16 +229,44 @@ impl AssocOp {
|
||||
}
|
||||
}
|
||||
|
||||
pub const PREC_CLOSURE: i8 = -40;
|
||||
pub const PREC_JUMP: i8 = -30;
|
||||
pub const PREC_RANGE: i8 = -10;
|
||||
// The range 2..=14 is reserved for AssocOp binary operator precedences.
|
||||
pub const PREC_PREFIX: i8 = 50;
|
||||
pub const PREC_UNAMBIGUOUS: i8 = 60;
|
||||
#[derive(Clone, Copy, PartialEq, PartialOrd)]
|
||||
pub enum ExprPrecedence {
|
||||
Closure,
|
||||
// return, break, yield
|
||||
Jump,
|
||||
// = += -= *= /= %= &= |= ^= <<= >>=
|
||||
Assign,
|
||||
// .. ..=
|
||||
Range,
|
||||
// ||
|
||||
LOr,
|
||||
// &&
|
||||
LAnd,
|
||||
// == != < > <= >=
|
||||
Compare,
|
||||
// |
|
||||
BitOr,
|
||||
// ^
|
||||
BitXor,
|
||||
// &
|
||||
BitAnd,
|
||||
// << >>
|
||||
Shift,
|
||||
// + -
|
||||
Sum,
|
||||
// * / %
|
||||
Product,
|
||||
// as
|
||||
Cast,
|
||||
// unary - * ! & &mut
|
||||
Prefix,
|
||||
// paths, loops, function calls, array indexing, field expressions, method calls
|
||||
Unambiguous,
|
||||
}
|
||||
|
||||
/// In `let p = e`, operators with precedence `<=` this one requires parentheses in `e`.
|
||||
pub fn prec_let_scrutinee_needs_par() -> usize {
|
||||
AssocOp::LAnd.precedence()
|
||||
pub fn prec_let_scrutinee_needs_par() -> ExprPrecedence {
|
||||
ExprPrecedence::LAnd
|
||||
}
|
||||
|
||||
/// Suppose we have `let _ = e` and the `order` of `e`.
|
||||
@ -246,8 +274,8 @@ pub fn prec_let_scrutinee_needs_par() -> usize {
|
||||
///
|
||||
/// Conversely, suppose that we have `(let _ = a) OP b` and `order` is that of `OP`.
|
||||
/// Can we print this as `let _ = a OP b`?
|
||||
pub fn needs_par_as_let_scrutinee(order: i8) -> bool {
|
||||
order <= prec_let_scrutinee_needs_par() as i8
|
||||
pub fn needs_par_as_let_scrutinee(order: ExprPrecedence) -> bool {
|
||||
order <= prec_let_scrutinee_needs_par()
|
||||
}
|
||||
|
||||
/// Expressions that syntactically contain an "exterior" struct literal i.e., not surrounded by any
|
||||
|
@ -5,7 +5,7 @@ use itertools::{Itertools, Position};
|
||||
use rustc_ast::ptr::P;
|
||||
use rustc_ast::util::classify;
|
||||
use rustc_ast::util::literal::escape_byte_str_symbol;
|
||||
use rustc_ast::util::parser::{self, AssocOp, Fixity};
|
||||
use rustc_ast::util::parser::{self, AssocOp, ExprPrecedence, Fixity};
|
||||
use rustc_ast::{
|
||||
self as ast, BlockCheckMode, FormatAlignment, FormatArgPosition, FormatArgsPiece, FormatCount,
|
||||
FormatDebugHex, FormatSign, FormatTrait, token,
|
||||
@ -214,7 +214,7 @@ impl<'a> State<'a> {
|
||||
fn print_expr_call(&mut self, func: &ast::Expr, args: &[P<ast::Expr>], fixup: FixupContext) {
|
||||
let needs_paren = match func.kind {
|
||||
ast::ExprKind::Field(..) => true,
|
||||
_ => func.precedence() < parser::PREC_UNAMBIGUOUS,
|
||||
_ => func.precedence() < ExprPrecedence::Unambiguous,
|
||||
};
|
||||
|
||||
// Independent of parenthesization related to precedence, we must
|
||||
@ -256,7 +256,7 @@ impl<'a> State<'a> {
|
||||
// a statement containing an expression.
|
||||
self.print_expr_cond_paren(
|
||||
receiver,
|
||||
receiver.precedence() < parser::PREC_UNAMBIGUOUS,
|
||||
receiver.precedence() < ExprPrecedence::Unambiguous,
|
||||
fixup,
|
||||
);
|
||||
|
||||
@ -276,7 +276,7 @@ impl<'a> State<'a> {
|
||||
fixup: FixupContext,
|
||||
) {
|
||||
let assoc_op = AssocOp::from_ast_binop(op.node);
|
||||
let binop_prec = assoc_op.precedence() as i8;
|
||||
let binop_prec = assoc_op.precedence();
|
||||
let left_prec = lhs.precedence();
|
||||
let right_prec = rhs.precedence();
|
||||
|
||||
@ -317,7 +317,7 @@ impl<'a> State<'a> {
|
||||
self.word(op.as_str());
|
||||
self.print_expr_cond_paren(
|
||||
expr,
|
||||
expr.precedence() < parser::PREC_PREFIX,
|
||||
expr.precedence() < ExprPrecedence::Prefix,
|
||||
fixup.subsequent_subexpression(),
|
||||
);
|
||||
}
|
||||
@ -339,7 +339,7 @@ impl<'a> State<'a> {
|
||||
}
|
||||
self.print_expr_cond_paren(
|
||||
expr,
|
||||
expr.precedence() < parser::PREC_PREFIX,
|
||||
expr.precedence() < ExprPrecedence::Prefix,
|
||||
fixup.subsequent_subexpression(),
|
||||
);
|
||||
}
|
||||
@ -423,10 +423,9 @@ impl<'a> State<'a> {
|
||||
self.print_token_literal(lit, expr.span)
|
||||
}
|
||||
ast::ExprKind::Cast(expr, ty) => {
|
||||
let prec = AssocOp::As.precedence() as i8;
|
||||
self.print_expr_cond_paren(
|
||||
expr,
|
||||
expr.precedence() < prec,
|
||||
expr.precedence() < ExprPrecedence::Cast,
|
||||
fixup.leftmost_subexpression(),
|
||||
);
|
||||
self.space();
|
||||
@ -503,7 +502,7 @@ impl<'a> State<'a> {
|
||||
MatchKind::Postfix => {
|
||||
self.print_expr_cond_paren(
|
||||
expr,
|
||||
expr.precedence() < parser::PREC_UNAMBIGUOUS,
|
||||
expr.precedence() < ExprPrecedence::Unambiguous,
|
||||
fixup,
|
||||
);
|
||||
self.word_nbsp(".match");
|
||||
@ -567,31 +566,31 @@ impl<'a> State<'a> {
|
||||
ast::ExprKind::Await(expr, _) => {
|
||||
self.print_expr_cond_paren(
|
||||
expr,
|
||||
expr.precedence() < parser::PREC_UNAMBIGUOUS,
|
||||
expr.precedence() < ExprPrecedence::Unambiguous,
|
||||
fixup,
|
||||
);
|
||||
self.word(".await");
|
||||
}
|
||||
ast::ExprKind::Assign(lhs, rhs, _) => {
|
||||
let prec = AssocOp::Assign.precedence() as i8;
|
||||
self.print_expr_cond_paren(
|
||||
lhs,
|
||||
lhs.precedence() <= prec,
|
||||
// Ranges are allowed on the right-hand side of assignment,
|
||||
// but not the left. `(a..b) = c` needs parentheses.
|
||||
lhs.precedence() <= ExprPrecedence::Range,
|
||||
fixup.leftmost_subexpression(),
|
||||
);
|
||||
self.space();
|
||||
self.word_space("=");
|
||||
self.print_expr_cond_paren(
|
||||
rhs,
|
||||
rhs.precedence() < prec,
|
||||
rhs.precedence() < ExprPrecedence::Assign,
|
||||
fixup.subsequent_subexpression(),
|
||||
);
|
||||
}
|
||||
ast::ExprKind::AssignOp(op, lhs, rhs) => {
|
||||
let prec = AssocOp::Assign.precedence() as i8;
|
||||
self.print_expr_cond_paren(
|
||||
lhs,
|
||||
lhs.precedence() <= prec,
|
||||
lhs.precedence() <= ExprPrecedence::Range,
|
||||
fixup.leftmost_subexpression(),
|
||||
);
|
||||
self.space();
|
||||
@ -599,14 +598,14 @@ impl<'a> State<'a> {
|
||||
self.word_space("=");
|
||||
self.print_expr_cond_paren(
|
||||
rhs,
|
||||
rhs.precedence() < prec,
|
||||
rhs.precedence() < ExprPrecedence::Assign,
|
||||
fixup.subsequent_subexpression(),
|
||||
);
|
||||
}
|
||||
ast::ExprKind::Field(expr, ident) => {
|
||||
self.print_expr_cond_paren(
|
||||
expr,
|
||||
expr.precedence() < parser::PREC_UNAMBIGUOUS,
|
||||
expr.precedence() < ExprPrecedence::Unambiguous,
|
||||
fixup,
|
||||
);
|
||||
self.word(".");
|
||||
@ -615,7 +614,7 @@ impl<'a> State<'a> {
|
||||
ast::ExprKind::Index(expr, index, _) => {
|
||||
self.print_expr_cond_paren(
|
||||
expr,
|
||||
expr.precedence() < parser::PREC_UNAMBIGUOUS,
|
||||
expr.precedence() < ExprPrecedence::Unambiguous,
|
||||
fixup.leftmost_subexpression(),
|
||||
);
|
||||
self.word("[");
|
||||
@ -627,7 +626,7 @@ impl<'a> State<'a> {
|
||||
// than `Assign`, but `x .. x = x` gives a parse error instead of `x .. (x = x)`.
|
||||
// Here we use a fake precedence value so that any child with lower precedence than
|
||||
// a "normal" binop gets parenthesized. (`LOr` is the lowest-precedence binop.)
|
||||
let fake_prec = AssocOp::LOr.precedence() as i8;
|
||||
let fake_prec = ExprPrecedence::LOr;
|
||||
if let Some(e) = start {
|
||||
self.print_expr_cond_paren(
|
||||
e,
|
||||
@ -662,7 +661,7 @@ impl<'a> State<'a> {
|
||||
expr,
|
||||
// Parenthesize if required by precedence, or in the
|
||||
// case of `break 'inner: loop { break 'inner 1 } + 1`
|
||||
expr.precedence() < parser::PREC_JUMP
|
||||
expr.precedence() < ExprPrecedence::Jump
|
||||
|| (opt_label.is_none() && classify::leading_labeled_expr(expr)),
|
||||
fixup.subsequent_subexpression(),
|
||||
);
|
||||
@ -681,7 +680,7 @@ impl<'a> State<'a> {
|
||||
self.word(" ");
|
||||
self.print_expr_cond_paren(
|
||||
expr,
|
||||
expr.precedence() < parser::PREC_JUMP,
|
||||
expr.precedence() < ExprPrecedence::Jump,
|
||||
fixup.subsequent_subexpression(),
|
||||
);
|
||||
}
|
||||
@ -694,7 +693,7 @@ impl<'a> State<'a> {
|
||||
self.word(" ");
|
||||
self.print_expr_cond_paren(
|
||||
expr,
|
||||
expr.precedence() < parser::PREC_JUMP,
|
||||
expr.precedence() < ExprPrecedence::Jump,
|
||||
fixup.subsequent_subexpression(),
|
||||
);
|
||||
}
|
||||
@ -704,7 +703,7 @@ impl<'a> State<'a> {
|
||||
self.word(" ");
|
||||
self.print_expr_cond_paren(
|
||||
result,
|
||||
result.precedence() < parser::PREC_JUMP,
|
||||
result.precedence() < ExprPrecedence::Jump,
|
||||
fixup.subsequent_subexpression(),
|
||||
);
|
||||
}
|
||||
@ -758,13 +757,13 @@ impl<'a> State<'a> {
|
||||
self.space();
|
||||
self.print_expr_cond_paren(
|
||||
expr,
|
||||
expr.precedence() < parser::PREC_JUMP,
|
||||
expr.precedence() < ExprPrecedence::Jump,
|
||||
fixup.subsequent_subexpression(),
|
||||
);
|
||||
}
|
||||
}
|
||||
ast::ExprKind::Try(e) => {
|
||||
self.print_expr_cond_paren(e, e.precedence() < parser::PREC_UNAMBIGUOUS, fixup);
|
||||
self.print_expr_cond_paren(e, e.precedence() < ExprPrecedence::Unambiguous, fixup);
|
||||
self.word("?")
|
||||
}
|
||||
ast::ExprKind::TryBlock(blk) => {
|
||||
|
@ -6,6 +6,7 @@ use std::path::{Path, PathBuf};
|
||||
use std::process::ExitStatus;
|
||||
|
||||
use rustc_abi::TargetDataLayoutErrors;
|
||||
use rustc_ast::util::parser::ExprPrecedence;
|
||||
use rustc_ast_pretty::pprust;
|
||||
use rustc_macros::Subdiagnostic;
|
||||
use rustc_span::Span;
|
||||
@ -298,6 +299,12 @@ impl IntoDiagArg for hir::def::Namespace {
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoDiagArg for ExprPrecedence {
|
||||
fn into_diag_arg(self) -> DiagArgValue {
|
||||
DiagArgValue::Number(self as i32)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct DiagSymbolList<S = Symbol>(Vec<S>);
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
use std::fmt;
|
||||
|
||||
use rustc_abi::ExternAbi;
|
||||
use rustc_ast::util::parser::{AssocOp, PREC_CLOSURE, PREC_JUMP, PREC_PREFIX, PREC_UNAMBIGUOUS};
|
||||
use rustc_ast::util::parser::{AssocOp, ExprPrecedence};
|
||||
use rustc_ast::{
|
||||
self as ast, Attribute, FloatTy, InlineAsmOptions, InlineAsmTemplatePiece, IntTy, Label,
|
||||
LitKind, TraitObjectSyntax, UintTy,
|
||||
@ -1708,22 +1708,22 @@ pub struct Expr<'hir> {
|
||||
}
|
||||
|
||||
impl Expr<'_> {
|
||||
pub fn precedence(&self) -> i8 {
|
||||
pub fn precedence(&self) -> ExprPrecedence {
|
||||
match self.kind {
|
||||
ExprKind::Closure { .. } => PREC_CLOSURE,
|
||||
ExprKind::Closure { .. } => ExprPrecedence::Closure,
|
||||
|
||||
ExprKind::Break(..)
|
||||
| ExprKind::Continue(..)
|
||||
| ExprKind::Ret(..)
|
||||
| ExprKind::Yield(..)
|
||||
| ExprKind::Become(..) => PREC_JUMP,
|
||||
| ExprKind::Become(..) => ExprPrecedence::Jump,
|
||||
|
||||
// Binop-like expr kinds, handled by `AssocOp`.
|
||||
ExprKind::Binary(op, ..) => AssocOp::from_ast_binop(op.node).precedence() as i8,
|
||||
ExprKind::Cast(..) => AssocOp::As.precedence() as i8,
|
||||
ExprKind::Binary(op, ..) => AssocOp::from_ast_binop(op.node).precedence(),
|
||||
ExprKind::Cast(..) => ExprPrecedence::Cast,
|
||||
|
||||
ExprKind::Assign(..) |
|
||||
ExprKind::AssignOp(..) => AssocOp::Assign.precedence() as i8,
|
||||
ExprKind::AssignOp(..) => ExprPrecedence::Assign,
|
||||
|
||||
// Unary, prefix
|
||||
ExprKind::AddrOf(..)
|
||||
@ -1732,7 +1732,7 @@ impl Expr<'_> {
|
||||
// need parens sometimes. E.g. we can print `(let _ = a) && b` as `let _ = a && b`
|
||||
// but we need to print `(let _ = a) < b` as-is with parens.
|
||||
| ExprKind::Let(..)
|
||||
| ExprKind::Unary(..) => PREC_PREFIX,
|
||||
| ExprKind::Unary(..) => ExprPrecedence::Prefix,
|
||||
|
||||
// Never need parens
|
||||
ExprKind::Array(_)
|
||||
@ -1753,7 +1753,7 @@ impl Expr<'_> {
|
||||
| ExprKind::Struct(..)
|
||||
| ExprKind::Tup(_)
|
||||
| ExprKind::Type(..)
|
||||
| ExprKind::Err(_) => PREC_UNAMBIGUOUS,
|
||||
| ExprKind::Err(_) => ExprPrecedence::Unambiguous,
|
||||
|
||||
ExprKind::DropTemps(ref expr, ..) => expr.precedence(),
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ use std::cell::Cell;
|
||||
use std::vec;
|
||||
|
||||
use rustc_abi::ExternAbi;
|
||||
use rustc_ast::util::parser::{self, AssocOp, Fixity};
|
||||
use rustc_ast::util::parser::{self, AssocOp, ExprPrecedence, Fixity};
|
||||
use rustc_ast_pretty::pp::Breaks::{Consistent, Inconsistent};
|
||||
use rustc_ast_pretty::pp::{self, Breaks};
|
||||
use rustc_ast_pretty::pprust::{Comments, PrintState};
|
||||
@ -1134,7 +1134,7 @@ impl<'a> State<'a> {
|
||||
fn print_expr_call(&mut self, func: &hir::Expr<'_>, args: &[hir::Expr<'_>]) {
|
||||
let needs_paren = match func.kind {
|
||||
hir::ExprKind::Field(..) => true,
|
||||
_ => func.precedence() < parser::PREC_UNAMBIGUOUS,
|
||||
_ => func.precedence() < ExprPrecedence::Unambiguous,
|
||||
};
|
||||
|
||||
self.print_expr_cond_paren(func, needs_paren);
|
||||
@ -1148,7 +1148,7 @@ impl<'a> State<'a> {
|
||||
args: &[hir::Expr<'_>],
|
||||
) {
|
||||
let base_args = args;
|
||||
self.print_expr_cond_paren(receiver, receiver.precedence() < parser::PREC_UNAMBIGUOUS);
|
||||
self.print_expr_cond_paren(receiver, receiver.precedence() < ExprPrecedence::Unambiguous);
|
||||
self.word(".");
|
||||
self.print_ident(segment.ident);
|
||||
|
||||
@ -1162,7 +1162,7 @@ impl<'a> State<'a> {
|
||||
|
||||
fn print_expr_binary(&mut self, op: hir::BinOp, lhs: &hir::Expr<'_>, rhs: &hir::Expr<'_>) {
|
||||
let assoc_op = AssocOp::from_ast_binop(op.node);
|
||||
let binop_prec = assoc_op.precedence() as i8;
|
||||
let binop_prec = assoc_op.precedence();
|
||||
let left_prec = lhs.precedence();
|
||||
let right_prec = rhs.precedence();
|
||||
|
||||
@ -1193,7 +1193,7 @@ impl<'a> State<'a> {
|
||||
|
||||
fn print_expr_unary(&mut self, op: hir::UnOp, expr: &hir::Expr<'_>) {
|
||||
self.word(op.as_str());
|
||||
self.print_expr_cond_paren(expr, expr.precedence() < parser::PREC_PREFIX)
|
||||
self.print_expr_cond_paren(expr, expr.precedence() < ExprPrecedence::Prefix);
|
||||
}
|
||||
|
||||
fn print_expr_addr_of(
|
||||
@ -1210,7 +1210,7 @@ impl<'a> State<'a> {
|
||||
self.print_mutability(mutability, true);
|
||||
}
|
||||
}
|
||||
self.print_expr_cond_paren(expr, expr.precedence() < parser::PREC_PREFIX)
|
||||
self.print_expr_cond_paren(expr, expr.precedence() < ExprPrecedence::Prefix);
|
||||
}
|
||||
|
||||
fn print_literal(&mut self, lit: &hir::Lit) {
|
||||
@ -1348,8 +1348,7 @@ impl<'a> State<'a> {
|
||||
self.print_literal(lit);
|
||||
}
|
||||
hir::ExprKind::Cast(expr, ty) => {
|
||||
let prec = AssocOp::As.precedence() as i8;
|
||||
self.print_expr_cond_paren(expr, expr.precedence() < prec);
|
||||
self.print_expr_cond_paren(expr, expr.precedence() < ExprPrecedence::Cast);
|
||||
self.space();
|
||||
self.word_space("as");
|
||||
self.print_type(ty);
|
||||
@ -1450,27 +1449,25 @@ impl<'a> State<'a> {
|
||||
self.print_block(blk);
|
||||
}
|
||||
hir::ExprKind::Assign(lhs, rhs, _) => {
|
||||
let prec = AssocOp::Assign.precedence() as i8;
|
||||
self.print_expr_cond_paren(lhs, lhs.precedence() <= prec);
|
||||
self.print_expr_cond_paren(lhs, lhs.precedence() <= ExprPrecedence::Assign);
|
||||
self.space();
|
||||
self.word_space("=");
|
||||
self.print_expr_cond_paren(rhs, rhs.precedence() < prec);
|
||||
self.print_expr_cond_paren(rhs, rhs.precedence() < ExprPrecedence::Assign);
|
||||
}
|
||||
hir::ExprKind::AssignOp(op, lhs, rhs) => {
|
||||
let prec = AssocOp::Assign.precedence() as i8;
|
||||
self.print_expr_cond_paren(lhs, lhs.precedence() <= prec);
|
||||
self.print_expr_cond_paren(lhs, lhs.precedence() <= ExprPrecedence::Assign);
|
||||
self.space();
|
||||
self.word(op.node.as_str());
|
||||
self.word_space("=");
|
||||
self.print_expr_cond_paren(rhs, rhs.precedence() < prec);
|
||||
self.print_expr_cond_paren(rhs, rhs.precedence() < ExprPrecedence::Assign);
|
||||
}
|
||||
hir::ExprKind::Field(expr, ident) => {
|
||||
self.print_expr_cond_paren(expr, expr.precedence() < parser::PREC_UNAMBIGUOUS);
|
||||
self.print_expr_cond_paren(expr, expr.precedence() < ExprPrecedence::Unambiguous);
|
||||
self.word(".");
|
||||
self.print_ident(ident);
|
||||
}
|
||||
hir::ExprKind::Index(expr, index, _) => {
|
||||
self.print_expr_cond_paren(expr, expr.precedence() < parser::PREC_UNAMBIGUOUS);
|
||||
self.print_expr_cond_paren(expr, expr.precedence() < ExprPrecedence::Unambiguous);
|
||||
self.word("[");
|
||||
self.print_expr(index);
|
||||
self.word("]");
|
||||
@ -1484,7 +1481,7 @@ impl<'a> State<'a> {
|
||||
}
|
||||
if let Some(expr) = opt_expr {
|
||||
self.space();
|
||||
self.print_expr_cond_paren(expr, expr.precedence() < parser::PREC_JUMP);
|
||||
self.print_expr_cond_paren(expr, expr.precedence() < ExprPrecedence::Jump);
|
||||
}
|
||||
}
|
||||
hir::ExprKind::Continue(destination) => {
|
||||
@ -1498,13 +1495,13 @@ impl<'a> State<'a> {
|
||||
self.word("return");
|
||||
if let Some(expr) = result {
|
||||
self.word(" ");
|
||||
self.print_expr_cond_paren(expr, expr.precedence() < parser::PREC_JUMP);
|
||||
self.print_expr_cond_paren(expr, expr.precedence() < ExprPrecedence::Jump);
|
||||
}
|
||||
}
|
||||
hir::ExprKind::Become(result) => {
|
||||
self.word("become");
|
||||
self.word(" ");
|
||||
self.print_expr_cond_paren(result, result.precedence() < parser::PREC_JUMP);
|
||||
self.print_expr_cond_paren(result, result.precedence() < ExprPrecedence::Jump);
|
||||
}
|
||||
hir::ExprKind::InlineAsm(asm) => {
|
||||
self.word("asm!");
|
||||
@ -1529,7 +1526,7 @@ impl<'a> State<'a> {
|
||||
}
|
||||
hir::ExprKind::Yield(expr, _) => {
|
||||
self.word_space("yield");
|
||||
self.print_expr_cond_paren(expr, expr.precedence() < parser::PREC_JUMP);
|
||||
self.print_expr_cond_paren(expr, expr.precedence() < ExprPrecedence::Jump);
|
||||
}
|
||||
hir::ExprKind::Err(_) => {
|
||||
self.popen();
|
||||
|
@ -1,6 +1,6 @@
|
||||
use std::iter;
|
||||
|
||||
use rustc_ast::util::parser::PREC_UNAMBIGUOUS;
|
||||
use rustc_ast::util::parser::ExprPrecedence;
|
||||
use rustc_errors::{Applicability, Diag, ErrorGuaranteed, StashKey};
|
||||
use rustc_hir::def::{self, CtorKind, Namespace, Res};
|
||||
use rustc_hir::def_id::DefId;
|
||||
@ -606,7 +606,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
};
|
||||
|
||||
if let Ok(rest_snippet) = rest_snippet {
|
||||
let sugg = if callee_expr.precedence() >= PREC_UNAMBIGUOUS {
|
||||
let sugg = if callee_expr.precedence() >= ExprPrecedence::Unambiguous {
|
||||
vec![
|
||||
(up_to_rcvr_span, "".to_string()),
|
||||
(rest_span, format!(".{}({rest_snippet}", segment.ident)),
|
||||
|
@ -28,6 +28,7 @@
|
||||
//! expression, `e as U2` is not necessarily so (in fact it will only be valid if
|
||||
//! `U1` coerces to `U2`).
|
||||
|
||||
use rustc_ast::util::parser::ExprPrecedence;
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_errors::codes::*;
|
||||
use rustc_errors::{Applicability, Diag, ErrorGuaranteed};
|
||||
@ -1108,7 +1109,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
|
||||
|
||||
fn lossy_provenance_ptr2int_lint(&self, fcx: &FnCtxt<'a, 'tcx>, t_c: ty::cast::IntTy) {
|
||||
let expr_prec = self.expr.precedence();
|
||||
let needs_parens = expr_prec < rustc_ast::util::parser::PREC_UNAMBIGUOUS;
|
||||
let needs_parens = expr_prec < ExprPrecedence::Unambiguous;
|
||||
|
||||
let needs_cast = !matches!(t_c, ty::cast::IntTy::U(ty::UintTy::Usize));
|
||||
let cast_span = self.expr_span.shrink_to_hi().to(self.cast_span);
|
||||
|
@ -2,7 +2,7 @@ use core::cmp::min;
|
||||
use core::iter;
|
||||
|
||||
use hir::def_id::LocalDefId;
|
||||
use rustc_ast::util::parser::PREC_UNAMBIGUOUS;
|
||||
use rustc_ast::util::parser::ExprPrecedence;
|
||||
use rustc_data_structures::packed::Pu128;
|
||||
use rustc_errors::{Applicability, Diag, MultiSpan};
|
||||
use rustc_hir as hir;
|
||||
@ -398,7 +398,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
// so we remove the user's `clone` call.
|
||||
{
|
||||
vec![(receiver_method.ident.span, conversion_method.name.to_string())]
|
||||
} else if expr.precedence() < PREC_UNAMBIGUOUS {
|
||||
} else if expr.precedence() < ExprPrecedence::Unambiguous {
|
||||
vec![
|
||||
(expr.span.shrink_to_lo(), "(".to_string()),
|
||||
(expr.span.shrink_to_hi(), format!(").{}()", conversion_method.name)),
|
||||
@ -1376,7 +1376,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
{
|
||||
let span = expr.span.find_oldest_ancestor_in_same_ctxt();
|
||||
|
||||
let mut sugg = if expr.precedence() >= PREC_UNAMBIGUOUS {
|
||||
let mut sugg = if expr.precedence() >= ExprPrecedence::Unambiguous {
|
||||
vec![(span.shrink_to_hi(), ".into()".to_owned())]
|
||||
} else {
|
||||
vec![
|
||||
@ -3000,7 +3000,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
"change the type of the numeric literal from `{checked_ty}` to `{expected_ty}`",
|
||||
);
|
||||
|
||||
let close_paren = if expr.precedence() < PREC_UNAMBIGUOUS {
|
||||
let close_paren = if expr.precedence() < ExprPrecedence::Unambiguous {
|
||||
sugg.push((expr.span.shrink_to_lo(), "(".to_string()));
|
||||
")"
|
||||
} else {
|
||||
@ -3025,7 +3025,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
let len = src.trim_end_matches(&checked_ty.to_string()).len();
|
||||
expr.span.with_lo(expr.span.lo() + BytePos(len as u32))
|
||||
},
|
||||
if expr.precedence() < PREC_UNAMBIGUOUS {
|
||||
if expr.precedence() < ExprPrecedence::Unambiguous {
|
||||
// Readd `)`
|
||||
format!("{expected_ty})")
|
||||
} else {
|
||||
|
@ -3,6 +3,7 @@
|
||||
use std::borrow::Cow;
|
||||
|
||||
use rustc_ast::token::Token;
|
||||
use rustc_ast::util::parser::ExprPrecedence;
|
||||
use rustc_ast::{Path, Visibility};
|
||||
use rustc_errors::codes::*;
|
||||
use rustc_errors::{
|
||||
@ -2686,7 +2687,7 @@ pub(crate) struct UnexpectedExpressionInPattern {
|
||||
/// Was a `RangePatternBound` expected?
|
||||
pub is_bound: bool,
|
||||
/// The unexpected expr's precedence (used in match arm guard suggestions).
|
||||
pub expr_precedence: i8,
|
||||
pub expr_precedence: ExprPrecedence,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
|
@ -10,7 +10,7 @@ use rustc_ast::ptr::P;
|
||||
use rustc_ast::token::{self, Delimiter, Token, TokenKind};
|
||||
use rustc_ast::util::case::Case;
|
||||
use rustc_ast::util::classify;
|
||||
use rustc_ast::util::parser::{AssocOp, Fixity, prec_let_scrutinee_needs_par};
|
||||
use rustc_ast::util::parser::{AssocOp, ExprPrecedence, Fixity, prec_let_scrutinee_needs_par};
|
||||
use rustc_ast::visit::{Visitor, walk_expr};
|
||||
use rustc_ast::{
|
||||
self as ast, AnonConst, Arm, AttrStyle, AttrVec, BinOp, BinOpKind, BlockCheckMode, CaptureBy,
|
||||
@ -128,7 +128,7 @@ impl<'a> Parser<'a> {
|
||||
/// followed by a subexpression (e.g. `1 + 2`).
|
||||
pub(super) fn parse_expr_assoc_with(
|
||||
&mut self,
|
||||
min_prec: Bound<usize>,
|
||||
min_prec: Bound<ExprPrecedence>,
|
||||
attrs: AttrWrapper,
|
||||
) -> PResult<'a, (P<Expr>, bool)> {
|
||||
let lhs = if self.token.is_range_separator() {
|
||||
@ -144,7 +144,7 @@ impl<'a> Parser<'a> {
|
||||
/// was actually parsed.
|
||||
pub(super) fn parse_expr_assoc_rest_with(
|
||||
&mut self,
|
||||
min_prec: Bound<usize>,
|
||||
min_prec: Bound<ExprPrecedence>,
|
||||
starts_stmt: bool,
|
||||
mut lhs: P<Expr>,
|
||||
) -> PResult<'a, (P<Expr>, bool)> {
|
||||
@ -455,7 +455,7 @@ impl<'a> Parser<'a> {
|
||||
/// The other two variants are handled in `parse_prefix_range_expr` below.
|
||||
fn parse_expr_range(
|
||||
&mut self,
|
||||
prec: usize,
|
||||
prec: ExprPrecedence,
|
||||
lhs: P<Expr>,
|
||||
op: AssocOp,
|
||||
cur_op_span: Span,
|
||||
|
@ -3,12 +3,11 @@ use std::ops::Bound;
|
||||
use rustc_ast::mut_visit::{self, MutVisitor};
|
||||
use rustc_ast::ptr::P;
|
||||
use rustc_ast::token::{self, BinOpToken, Delimiter, IdentIsRaw, Token};
|
||||
use rustc_ast::util::parser::AssocOp;
|
||||
use rustc_ast::util::parser::ExprPrecedence;
|
||||
use rustc_ast::visit::{self, Visitor};
|
||||
use rustc_ast::{
|
||||
self as ast, Arm, AttrVec, BinOpKind, BindingMode, ByRef, Expr, ExprKind, LocalKind, MacCall,
|
||||
Mutability, Pat, PatField, PatFieldsRest, PatKind, Path, QSelf, RangeEnd, RangeSyntax, Stmt,
|
||||
StmtKind,
|
||||
self as ast, Arm, AttrVec, BindingMode, ByRef, Expr, ExprKind, LocalKind, MacCall, Mutability,
|
||||
Pat, PatField, PatFieldsRest, PatKind, Path, QSelf, RangeEnd, RangeSyntax, Stmt, StmtKind,
|
||||
};
|
||||
use rustc_ast_pretty::pprust;
|
||||
use rustc_errors::{Applicability, Diag, DiagArgValue, PResult, StashKey};
|
||||
@ -548,10 +547,7 @@ impl<'a> Parser<'a> {
|
||||
// HACK: a neater way would be preferable.
|
||||
let expr = match &err.args["expr_precedence"] {
|
||||
DiagArgValue::Number(expr_precedence) => {
|
||||
if *expr_precedence
|
||||
<= AssocOp::from_ast_binop(BinOpKind::Eq).precedence()
|
||||
as i32
|
||||
{
|
||||
if *expr_precedence <= ExprPrecedence::Compare as i32 {
|
||||
format!("({expr})")
|
||||
} else {
|
||||
format!("{expr}")
|
||||
@ -573,9 +569,7 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
Some(guard) => {
|
||||
// Are parentheses required around the old guard?
|
||||
let wrap_guard = guard.precedence()
|
||||
<= AssocOp::from_ast_binop(BinOpKind::And).precedence()
|
||||
as i8;
|
||||
let wrap_guard = guard.precedence() <= ExprPrecedence::LAnd;
|
||||
|
||||
err.subdiagnostic(
|
||||
UnexpectedExpressionInPatternSugg::UpdateGuard {
|
||||
|
@ -7,7 +7,7 @@ use clippy_utils::{
|
||||
peel_middle_ty_refs,
|
||||
};
|
||||
use core::mem;
|
||||
use rustc_ast::util::parser::{PREC_PREFIX, PREC_UNAMBIGUOUS};
|
||||
use rustc_ast::util::parser::ExprPrecedence;
|
||||
use rustc_data_structures::fx::FxIndexMap;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::def_id::DefId;
|
||||
@ -963,7 +963,7 @@ fn report<'tcx>(
|
||||
// expr_str (the suggestion) is never shown if is_final_ufcs is true, since it's
|
||||
// `expr.kind == ExprKind::Call`. Therefore, this is, afaik, always unnecessary.
|
||||
/*
|
||||
expr_str = if !expr_is_macro_call && is_final_ufcs && expr.precedence() < PREC_PREFIX {
|
||||
expr_str = if !expr_is_macro_call && is_final_ufcs && expr.precedence() < ExprPrecedence::Prefix {
|
||||
Cow::Owned(format!("({expr_str})"))
|
||||
} else {
|
||||
expr_str
|
||||
@ -999,13 +999,13 @@ fn report<'tcx>(
|
||||
data.first_expr.span,
|
||||
state.msg,
|
||||
|diag| {
|
||||
let (precedence, calls_field) = match cx.tcx.parent_hir_node(data.first_expr.hir_id) {
|
||||
let needs_paren = match cx.tcx.parent_hir_node(data.first_expr.hir_id) {
|
||||
Node::Expr(e) => match e.kind {
|
||||
ExprKind::Call(callee, _) if callee.hir_id != data.first_expr.hir_id => (0, false),
|
||||
ExprKind::Call(..) => (PREC_UNAMBIGUOUS, matches!(expr.kind, ExprKind::Field(..))),
|
||||
_ => (e.precedence(), false),
|
||||
ExprKind::Call(callee, _) if callee.hir_id != data.first_expr.hir_id => false,
|
||||
ExprKind::Call(..) => expr.precedence() < ExprPrecedence::Unambiguous || matches!(expr.kind, ExprKind::Field(..)),
|
||||
_ => expr.precedence() < e.precedence(),
|
||||
},
|
||||
_ => (0, false),
|
||||
_ => false,
|
||||
};
|
||||
let is_in_tuple = matches!(
|
||||
get_parent_expr(cx, data.first_expr),
|
||||
@ -1016,7 +1016,7 @@ fn report<'tcx>(
|
||||
);
|
||||
|
||||
let sugg = if !snip_is_macro
|
||||
&& (calls_field || expr.precedence() < precedence)
|
||||
&& needs_paren
|
||||
&& !has_enclosing_paren(&snip)
|
||||
&& !is_in_tuple
|
||||
{
|
||||
@ -1049,16 +1049,16 @@ fn report<'tcx>(
|
||||
}
|
||||
}
|
||||
|
||||
let (prefix, precedence) = match mutability {
|
||||
let (prefix, needs_paren) = match mutability {
|
||||
Some(mutability) if !ty.is_ref() => {
|
||||
let prefix = match mutability {
|
||||
Mutability::Not => "&",
|
||||
Mutability::Mut => "&mut ",
|
||||
};
|
||||
(prefix, PREC_PREFIX)
|
||||
(prefix, expr.precedence() < ExprPrecedence::Prefix)
|
||||
},
|
||||
None if !ty.is_ref() && data.adjusted_ty.is_ref() => ("&", 0),
|
||||
_ => ("", 0),
|
||||
None if !ty.is_ref() && data.adjusted_ty.is_ref() => ("&", false),
|
||||
_ => ("", false),
|
||||
};
|
||||
span_lint_hir_and_then(
|
||||
cx,
|
||||
@ -1070,7 +1070,7 @@ fn report<'tcx>(
|
||||
let mut app = Applicability::MachineApplicable;
|
||||
let (snip, snip_is_macro) =
|
||||
snippet_with_context(cx, expr.span, data.first_expr.span.ctxt(), "..", &mut app);
|
||||
let sugg = if !snip_is_macro && expr.precedence() < precedence && !has_enclosing_paren(&snip) {
|
||||
let sugg = if !snip_is_macro && needs_paren && !has_enclosing_paren(&snip) {
|
||||
format!("{prefix}({snip})")
|
||||
} else {
|
||||
format!("{prefix}{snip}")
|
||||
@ -1157,7 +1157,7 @@ impl<'tcx> Dereferencing<'tcx> {
|
||||
},
|
||||
Some(parent) if !parent.span.from_expansion() => {
|
||||
// Double reference might be needed at this point.
|
||||
if parent.precedence() == PREC_UNAMBIGUOUS {
|
||||
if parent.precedence() == ExprPrecedence::Unambiguous {
|
||||
// Parentheses would be needed here, don't lint.
|
||||
*outer_pat = None;
|
||||
} else {
|
||||
|
@ -3,7 +3,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::source::{indent_of, snippet, snippet_with_applicability};
|
||||
use clippy_utils::visitors::contains_break_or_continue;
|
||||
use rustc_ast::Mutability;
|
||||
use rustc_ast::util::parser::PREC_PREFIX;
|
||||
use rustc_ast::util::parser::ExprPrecedence;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{BorrowKind, Expr, ExprKind, Pat, PatKind, is_range_literal};
|
||||
use rustc_lint::LateContext;
|
||||
@ -84,7 +84,7 @@ pub(super) fn check<'tcx>(
|
||||
if !prefix.is_empty()
|
||||
&& (
|
||||
// Precedence of internal expression is less than or equal to precedence of `&expr`.
|
||||
arg_expression.precedence() <= PREC_PREFIX || is_range_literal(arg_expression)
|
||||
arg_expression.precedence() <= ExprPrecedence::Prefix || is_range_literal(arg_expression)
|
||||
)
|
||||
{
|
||||
arg_snip = format!("({arg_snip})").into();
|
||||
|
@ -7,7 +7,7 @@ use clippy_utils::{
|
||||
CaptureKind, can_move_expr_to_closure, is_else_clause, is_lint_allowed, is_res_lang_ctor, path_res,
|
||||
path_to_local_id, peel_blocks, peel_hir_expr_refs, peel_hir_expr_while,
|
||||
};
|
||||
use rustc_ast::util::parser::PREC_UNAMBIGUOUS;
|
||||
use rustc_ast::util::parser::ExprPrecedence;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::LangItem::{OptionNone, OptionSome};
|
||||
use rustc_hir::def::Res;
|
||||
@ -117,7 +117,7 @@ where
|
||||
// it's being passed by value.
|
||||
let scrutinee = peel_hir_expr_refs(scrutinee).0;
|
||||
let (scrutinee_str, _) = snippet_with_context(cx, scrutinee.span, expr_ctxt, "..", &mut app);
|
||||
let scrutinee_str = if scrutinee.span.eq_ctxt(expr.span) && scrutinee.precedence() < PREC_UNAMBIGUOUS {
|
||||
let scrutinee_str = if scrutinee.span.eq_ctxt(expr.span) && scrutinee.precedence() < ExprPrecedence::Unambiguous {
|
||||
format!("({scrutinee_str})")
|
||||
} else {
|
||||
scrutinee_str.into()
|
||||
|
@ -2,7 +2,7 @@ use clippy_utils::consts::{self, Constant};
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::source::snippet_with_context;
|
||||
use clippy_utils::sugg::has_enclosing_paren;
|
||||
use rustc_ast::util::parser::PREC_PREFIX;
|
||||
use rustc_ast::util::parser::ExprPrecedence;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{BinOpKind, Expr, ExprKind, UnOp};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
@ -58,7 +58,7 @@ fn check_mul(cx: &LateContext<'_>, span: Span, lit: &Expr<'_>, exp: &Expr<'_>) {
|
||||
{
|
||||
let mut applicability = Applicability::MachineApplicable;
|
||||
let (snip, from_macro) = snippet_with_context(cx, exp.span, span.ctxt(), "..", &mut applicability);
|
||||
let suggestion = if !from_macro && exp.precedence() < PREC_PREFIX && !has_enclosing_paren(&snip) {
|
||||
let suggestion = if !from_macro && exp.precedence() < ExprPrecedence::Prefix && !has_enclosing_paren(&snip) {
|
||||
format!("-({snip})")
|
||||
} else {
|
||||
format!("-{snip}")
|
||||
|
@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::source::snippet_with_context;
|
||||
use clippy_utils::ty::is_type_lang_item;
|
||||
use clippy_utils::{get_parent_expr, peel_middle_ty_refs};
|
||||
use rustc_ast::util::parser::PREC_PREFIX;
|
||||
use rustc_ast::util::parser::ExprPrecedence;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{BorrowKind, Expr, ExprKind, LangItem, Mutability};
|
||||
use rustc_lint::{LateContext, LateLintPass, Lint};
|
||||
@ -85,7 +85,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantSlicing {
|
||||
let (expr_ty, expr_ref_count) = peel_middle_ty_refs(cx.typeck_results().expr_ty(expr));
|
||||
let (indexed_ty, indexed_ref_count) = peel_middle_ty_refs(cx.typeck_results().expr_ty(indexed));
|
||||
let parent_expr = get_parent_expr(cx, expr);
|
||||
let needs_parens_for_prefix = parent_expr.is_some_and(|parent| parent.precedence() > PREC_PREFIX);
|
||||
let needs_parens_for_prefix = parent_expr.is_some_and(|parent| parent.precedence() > ExprPrecedence::Prefix);
|
||||
|
||||
if expr_ty == indexed_ty {
|
||||
if expr_ref_count > indexed_ref_count {
|
||||
|
@ -1,7 +1,7 @@
|
||||
use super::TRANSMUTES_EXPRESSIBLE_AS_PTR_CASTS;
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::sugg::Sugg;
|
||||
use rustc_ast::util::parser::AssocOp;
|
||||
use rustc_ast::util::parser::ExprPrecedence;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::{Expr, Node};
|
||||
use rustc_hir_typeck::cast::check_cast;
|
||||
@ -44,8 +44,7 @@ pub(super) fn check<'tcx>(
|
||||
};
|
||||
|
||||
if let Node::Expr(parent) = cx.tcx.parent_hir_node(e.hir_id)
|
||||
&& parent.precedence()
|
||||
> i8::try_from(AssocOp::As.precedence()).expect("AssocOp always returns a precedence < 128")
|
||||
&& parent.precedence() > ExprPrecedence::Cast
|
||||
{
|
||||
sugg = format!("({sugg})");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user