Inline ExprPrecedence::order into Expr::precedence
This commit is contained in:
parent
23e7ecb349
commit
e5f1555000
16 changed files with 146 additions and 225 deletions
|
@ -39,7 +39,9 @@ pub use crate::format::*;
|
||||||
use crate::ptr::P;
|
use crate::ptr::P;
|
||||||
use crate::token::{self, CommentKind, Delimiter};
|
use crate::token::{self, CommentKind, Delimiter};
|
||||||
use crate::tokenstream::{DelimSpan, LazyAttrTokenStream, TokenStream};
|
use crate::tokenstream::{DelimSpan, LazyAttrTokenStream, TokenStream};
|
||||||
pub use crate::util::parser::ExprPrecedence;
|
use crate::util::parser::{
|
||||||
|
AssocOp, PREC_CLOSURE, PREC_JUMP, PREC_PREFIX, PREC_RANGE, PREC_UNAMBIGUOUS,
|
||||||
|
};
|
||||||
|
|
||||||
/// A "Label" is an identifier of some point in sources,
|
/// A "Label" is an identifier of some point in sources,
|
||||||
/// e.g. in the following code:
|
/// e.g. in the following code:
|
||||||
|
@ -1319,53 +1321,71 @@ impl Expr {
|
||||||
Some(P(Ty { kind, id: self.id, span: self.span, tokens: None }))
|
Some(P(Ty { kind, id: self.id, span: self.span, tokens: None }))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn precedence(&self) -> ExprPrecedence {
|
pub fn precedence(&self) -> i8 {
|
||||||
match self.kind {
|
match self.kind {
|
||||||
ExprKind::Array(_) => ExprPrecedence::Array,
|
ExprKind::Closure(..) => PREC_CLOSURE,
|
||||||
ExprKind::ConstBlock(_) => ExprPrecedence::ConstBlock,
|
|
||||||
ExprKind::Call(..) => ExprPrecedence::Call,
|
ExprKind::Break(..)
|
||||||
ExprKind::MethodCall(..) => ExprPrecedence::MethodCall,
|
| ExprKind::Continue(..)
|
||||||
ExprKind::Tup(_) => ExprPrecedence::Tup,
|
| ExprKind::Ret(..)
|
||||||
ExprKind::Binary(op, ..) => ExprPrecedence::Binary(op.node),
|
| ExprKind::Yield(..)
|
||||||
ExprKind::Unary(..) => ExprPrecedence::Unary,
|
| ExprKind::Yeet(..)
|
||||||
ExprKind::Lit(_) | ExprKind::IncludedBytes(..) => ExprPrecedence::Lit,
|
| ExprKind::Become(..) => PREC_JUMP,
|
||||||
ExprKind::Cast(..) => ExprPrecedence::Cast,
|
|
||||||
ExprKind::Let(..) => ExprPrecedence::Let,
|
// `Range` claims to have higher precedence than `Assign`, but `x .. x = x` fails to
|
||||||
ExprKind::If(..) => ExprPrecedence::If,
|
// parse, instead of parsing as `(x .. x) = x`. Giving `Range` a lower precedence
|
||||||
ExprKind::While(..) => ExprPrecedence::While,
|
// ensures that `pprust` will add parentheses in the right places to get the desired
|
||||||
ExprKind::ForLoop { .. } => ExprPrecedence::ForLoop,
|
// parse.
|
||||||
ExprKind::Loop(..) => ExprPrecedence::Loop,
|
ExprKind::Range(..) => PREC_RANGE,
|
||||||
ExprKind::Match(_, _, MatchKind::Prefix) => ExprPrecedence::Match,
|
|
||||||
ExprKind::Match(_, _, MatchKind::Postfix) => ExprPrecedence::PostfixMatch,
|
// Binop-like expr kinds, handled by `AssocOp`.
|
||||||
ExprKind::Closure(..) => ExprPrecedence::Closure,
|
ExprKind::Binary(op, ..) => AssocOp::from_ast_binop(op.node).precedence() as i8,
|
||||||
ExprKind::Block(..) => ExprPrecedence::Block,
|
ExprKind::Cast(..) => AssocOp::As.precedence() as i8,
|
||||||
ExprKind::TryBlock(..) => ExprPrecedence::TryBlock,
|
|
||||||
ExprKind::Gen(..) => ExprPrecedence::Gen,
|
ExprKind::Assign(..) |
|
||||||
ExprKind::Await(..) => ExprPrecedence::Await,
|
ExprKind::AssignOp(..) => AssocOp::Assign.precedence() as i8,
|
||||||
ExprKind::Assign(..) => ExprPrecedence::Assign,
|
|
||||||
ExprKind::AssignOp(..) => ExprPrecedence::AssignOp,
|
// Unary, prefix
|
||||||
ExprKind::Field(..) => ExprPrecedence::Field,
|
ExprKind::AddrOf(..)
|
||||||
ExprKind::Index(..) => ExprPrecedence::Index,
|
// Here `let pats = expr` has `let pats =` as a "unary" prefix of `expr`.
|
||||||
ExprKind::Range(..) => ExprPrecedence::Range,
|
// However, this is not exactly right. When `let _ = a` is the LHS of a binop we
|
||||||
ExprKind::Underscore => ExprPrecedence::Path,
|
// need parens sometimes. E.g. we can print `(let _ = a) && b` as `let _ = a && b`
|
||||||
ExprKind::Path(..) => ExprPrecedence::Path,
|
// but we need to print `(let _ = a) < b` as-is with parens.
|
||||||
ExprKind::AddrOf(..) => ExprPrecedence::AddrOf,
|
| ExprKind::Let(..)
|
||||||
ExprKind::Break(..) => ExprPrecedence::Break,
|
| ExprKind::Unary(..) => PREC_PREFIX,
|
||||||
ExprKind::Continue(..) => ExprPrecedence::Continue,
|
|
||||||
ExprKind::Ret(..) => ExprPrecedence::Ret,
|
// Never need parens
|
||||||
ExprKind::Struct(..) => ExprPrecedence::Struct,
|
ExprKind::Array(_)
|
||||||
ExprKind::Repeat(..) => ExprPrecedence::Repeat,
|
| ExprKind::Await(..)
|
||||||
ExprKind::Paren(..) => ExprPrecedence::Paren,
|
| ExprKind::Block(..)
|
||||||
ExprKind::Try(..) => ExprPrecedence::Try,
|
| ExprKind::Call(..)
|
||||||
ExprKind::Yield(..) => ExprPrecedence::Yield,
|
| ExprKind::ConstBlock(_)
|
||||||
ExprKind::Yeet(..) => ExprPrecedence::Yeet,
|
| ExprKind::Field(..)
|
||||||
ExprKind::Become(..) => ExprPrecedence::Become,
|
| ExprKind::ForLoop { .. }
|
||||||
ExprKind::InlineAsm(..)
|
|
||||||
| ExprKind::Type(..)
|
|
||||||
| ExprKind::OffsetOf(..)
|
|
||||||
| ExprKind::FormatArgs(..)
|
| ExprKind::FormatArgs(..)
|
||||||
| ExprKind::MacCall(..) => ExprPrecedence::Mac,
|
| ExprKind::Gen(..)
|
||||||
ExprKind::Err(_) | ExprKind::Dummy => ExprPrecedence::Err,
|
| ExprKind::If(..)
|
||||||
|
| ExprKind::IncludedBytes(..)
|
||||||
|
| ExprKind::Index(..)
|
||||||
|
| ExprKind::InlineAsm(..)
|
||||||
|
| ExprKind::Lit(_)
|
||||||
|
| ExprKind::Loop(..)
|
||||||
|
| ExprKind::MacCall(..)
|
||||||
|
| ExprKind::Match(..)
|
||||||
|
| ExprKind::MethodCall(..)
|
||||||
|
| ExprKind::OffsetOf(..)
|
||||||
|
| ExprKind::Paren(..)
|
||||||
|
| ExprKind::Path(..)
|
||||||
|
| ExprKind::Repeat(..)
|
||||||
|
| ExprKind::Struct(..)
|
||||||
|
| ExprKind::Try(..)
|
||||||
|
| ExprKind::TryBlock(..)
|
||||||
|
| ExprKind::Tup(_)
|
||||||
|
| ExprKind::Type(..)
|
||||||
|
| ExprKind::Underscore
|
||||||
|
| ExprKind::While(..)
|
||||||
|
| ExprKind::Err(_)
|
||||||
|
| ExprKind::Dummy => PREC_UNAMBIGUOUS,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -237,121 +237,6 @@ pub const PREC_PREFIX: i8 = 50;
|
||||||
pub const PREC_UNAMBIGUOUS: i8 = 60;
|
pub const PREC_UNAMBIGUOUS: i8 = 60;
|
||||||
pub const PREC_FORCE_PAREN: i8 = 100;
|
pub const PREC_FORCE_PAREN: i8 = 100;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
|
||||||
pub enum ExprPrecedence {
|
|
||||||
Closure,
|
|
||||||
Break,
|
|
||||||
Continue,
|
|
||||||
Ret,
|
|
||||||
Yield,
|
|
||||||
Yeet,
|
|
||||||
Become,
|
|
||||||
|
|
||||||
Range,
|
|
||||||
|
|
||||||
Binary(BinOpKind),
|
|
||||||
|
|
||||||
Cast,
|
|
||||||
|
|
||||||
Assign,
|
|
||||||
AssignOp,
|
|
||||||
|
|
||||||
AddrOf,
|
|
||||||
Let,
|
|
||||||
Unary,
|
|
||||||
|
|
||||||
Call,
|
|
||||||
MethodCall,
|
|
||||||
Field,
|
|
||||||
Index,
|
|
||||||
Try,
|
|
||||||
Mac,
|
|
||||||
|
|
||||||
Array,
|
|
||||||
Repeat,
|
|
||||||
Tup,
|
|
||||||
Lit,
|
|
||||||
Path,
|
|
||||||
Paren,
|
|
||||||
If,
|
|
||||||
While,
|
|
||||||
ForLoop,
|
|
||||||
Loop,
|
|
||||||
Match,
|
|
||||||
PostfixMatch,
|
|
||||||
ConstBlock,
|
|
||||||
Block,
|
|
||||||
TryBlock,
|
|
||||||
Struct,
|
|
||||||
Gen,
|
|
||||||
Await,
|
|
||||||
Err,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ExprPrecedence {
|
|
||||||
pub fn order(self) -> i8 {
|
|
||||||
match self {
|
|
||||||
ExprPrecedence::Closure => PREC_CLOSURE,
|
|
||||||
|
|
||||||
ExprPrecedence::Break
|
|
||||||
| ExprPrecedence::Continue
|
|
||||||
| ExprPrecedence::Ret
|
|
||||||
| ExprPrecedence::Yield
|
|
||||||
| ExprPrecedence::Yeet
|
|
||||||
| ExprPrecedence::Become => PREC_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.
|
|
||||||
ExprPrecedence::Range => PREC_RANGE,
|
|
||||||
|
|
||||||
// Binop-like expr kinds, handled by `AssocOp`.
|
|
||||||
ExprPrecedence::Binary(op) => AssocOp::from_ast_binop(op).precedence() as i8,
|
|
||||||
ExprPrecedence::Cast => AssocOp::As.precedence() as i8,
|
|
||||||
|
|
||||||
ExprPrecedence::Assign |
|
|
||||||
ExprPrecedence::AssignOp => AssocOp::Assign.precedence() as i8,
|
|
||||||
|
|
||||||
// Unary, prefix
|
|
||||||
ExprPrecedence::AddrOf
|
|
||||||
// Here `let pats = expr` has `let pats =` as a "unary" prefix of `expr`.
|
|
||||||
// However, this is not exactly right. When `let _ = a` is the LHS of a binop we
|
|
||||||
// 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.
|
|
||||||
| ExprPrecedence::Let
|
|
||||||
| ExprPrecedence::Unary => PREC_PREFIX,
|
|
||||||
|
|
||||||
// Never need parens
|
|
||||||
ExprPrecedence::Array
|
|
||||||
| ExprPrecedence::Await
|
|
||||||
| ExprPrecedence::Block
|
|
||||||
| ExprPrecedence::Call
|
|
||||||
| ExprPrecedence::ConstBlock
|
|
||||||
| ExprPrecedence::Field
|
|
||||||
| ExprPrecedence::ForLoop
|
|
||||||
| ExprPrecedence::Gen
|
|
||||||
| ExprPrecedence::If
|
|
||||||
| ExprPrecedence::Index
|
|
||||||
| ExprPrecedence::Lit
|
|
||||||
| ExprPrecedence::Loop
|
|
||||||
| ExprPrecedence::Mac
|
|
||||||
| ExprPrecedence::Match
|
|
||||||
| ExprPrecedence::MethodCall
|
|
||||||
| ExprPrecedence::Paren
|
|
||||||
| ExprPrecedence::Path
|
|
||||||
| ExprPrecedence::PostfixMatch
|
|
||||||
| ExprPrecedence::Repeat
|
|
||||||
| ExprPrecedence::Struct
|
|
||||||
| ExprPrecedence::Try
|
|
||||||
| ExprPrecedence::TryBlock
|
|
||||||
| ExprPrecedence::Tup
|
|
||||||
| ExprPrecedence::While
|
|
||||||
| ExprPrecedence::Err => PREC_UNAMBIGUOUS,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// In `let p = e`, operators with precedence `<=` this one requires parentheses in `e`.
|
/// In `let p = e`, operators with precedence `<=` this one requires parentheses in `e`.
|
||||||
pub fn prec_let_scrutinee_needs_par() -> usize {
|
pub fn prec_let_scrutinee_needs_par() -> usize {
|
||||||
AssocOp::LAnd.precedence()
|
AssocOp::LAnd.precedence()
|
||||||
|
|
|
@ -59,7 +59,7 @@ impl<'a> State<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_expr_maybe_paren(&mut self, expr: &ast::Expr, prec: i8, fixup: FixupContext) {
|
fn print_expr_maybe_paren(&mut self, expr: &ast::Expr, prec: i8, fixup: FixupContext) {
|
||||||
self.print_expr_cond_paren(expr, expr.precedence().order() < prec, fixup);
|
self.print_expr_cond_paren(expr, expr.precedence() < prec, fixup);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Prints an expr using syntax that's acceptable in a condition position, such as the `cond` in
|
/// Prints an expr using syntax that's acceptable in a condition position, such as the `cond` in
|
||||||
|
@ -615,7 +615,7 @@ impl<'a> State<'a> {
|
||||||
expr,
|
expr,
|
||||||
// Parenthesize if required by precedence, or in the
|
// Parenthesize if required by precedence, or in the
|
||||||
// case of `break 'inner: loop { break 'inner 1 } + 1`
|
// case of `break 'inner: loop { break 'inner 1 } + 1`
|
||||||
expr.precedence().order() < parser::PREC_JUMP
|
expr.precedence() < parser::PREC_JUMP
|
||||||
|| (opt_label.is_none() && classify::leading_labeled_expr(expr)),
|
|| (opt_label.is_none() && classify::leading_labeled_expr(expr)),
|
||||||
fixup.subsequent_subexpression(),
|
fixup.subsequent_subexpression(),
|
||||||
);
|
);
|
||||||
|
|
|
@ -191,6 +191,6 @@ impl FixupContext {
|
||||||
/// "let chain".
|
/// "let chain".
|
||||||
pub(crate) fn needs_par_as_let_scrutinee(self, expr: &Expr) -> bool {
|
pub(crate) fn needs_par_as_let_scrutinee(self, expr: &Expr) -> bool {
|
||||||
self.parenthesize_exterior_struct_lit && parser::contains_exterior_struct_lit(expr)
|
self.parenthesize_exterior_struct_lit && parser::contains_exterior_struct_lit(expr)
|
||||||
|| parser::needs_par_as_let_scrutinee(expr.precedence().order())
|
|| parser::needs_par_as_let_scrutinee(expr.precedence())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use rustc_abi::ExternAbi;
|
use rustc_abi::ExternAbi;
|
||||||
use rustc_ast::util::parser::ExprPrecedence;
|
use rustc_ast::util::parser::{AssocOp, PREC_CLOSURE, PREC_JUMP, PREC_PREFIX, PREC_UNAMBIGUOUS};
|
||||||
use rustc_ast::{
|
use rustc_ast::{
|
||||||
self as ast, Attribute, FloatTy, InlineAsmOptions, InlineAsmTemplatePiece, IntTy, Label,
|
self as ast, Attribute, FloatTy, InlineAsmOptions, InlineAsmTemplatePiece, IntTy, Label,
|
||||||
LitKind, TraitObjectSyntax, UintTy,
|
LitKind, TraitObjectSyntax, UintTy,
|
||||||
|
@ -1719,41 +1719,54 @@ pub struct Expr<'hir> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Expr<'_> {
|
impl Expr<'_> {
|
||||||
pub fn precedence(&self) -> ExprPrecedence {
|
pub fn precedence(&self) -> i8 {
|
||||||
match self.kind {
|
match self.kind {
|
||||||
ExprKind::ConstBlock(_) => ExprPrecedence::ConstBlock,
|
ExprKind::Closure { .. } => PREC_CLOSURE,
|
||||||
ExprKind::Array(_) => ExprPrecedence::Array,
|
|
||||||
ExprKind::Call(..) => ExprPrecedence::Call,
|
ExprKind::Break(..)
|
||||||
ExprKind::MethodCall(..) => ExprPrecedence::MethodCall,
|
| ExprKind::Continue(..)
|
||||||
ExprKind::Tup(_) => ExprPrecedence::Tup,
|
| ExprKind::Ret(..)
|
||||||
ExprKind::Binary(op, ..) => ExprPrecedence::Binary(op.node),
|
| ExprKind::Yield(..)
|
||||||
ExprKind::Unary(..) => ExprPrecedence::Unary,
|
| ExprKind::Become(..) => PREC_JUMP,
|
||||||
ExprKind::Lit(_) => ExprPrecedence::Lit,
|
|
||||||
ExprKind::Cast(..) => ExprPrecedence::Cast,
|
// 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::Assign(..) |
|
||||||
|
ExprKind::AssignOp(..) => AssocOp::Assign.precedence() as i8,
|
||||||
|
|
||||||
|
// Unary, prefix
|
||||||
|
ExprKind::AddrOf(..)
|
||||||
|
// Here `let pats = expr` has `let pats =` as a "unary" prefix of `expr`.
|
||||||
|
// However, this is not exactly right. When `let _ = a` is the LHS of a binop we
|
||||||
|
// 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,
|
||||||
|
|
||||||
|
// Never need parens
|
||||||
|
ExprKind::Array(_)
|
||||||
|
| ExprKind::Block(..)
|
||||||
|
| ExprKind::Call(..)
|
||||||
|
| ExprKind::ConstBlock(_)
|
||||||
|
| ExprKind::Field(..)
|
||||||
|
| ExprKind::If(..)
|
||||||
|
| ExprKind::Index(..)
|
||||||
|
| ExprKind::InlineAsm(..)
|
||||||
|
| ExprKind::Lit(_)
|
||||||
|
| ExprKind::Loop(..)
|
||||||
|
| ExprKind::Match(..)
|
||||||
|
| ExprKind::MethodCall(..)
|
||||||
|
| ExprKind::OffsetOf(..)
|
||||||
|
| ExprKind::Path(..)
|
||||||
|
| ExprKind::Repeat(..)
|
||||||
|
| ExprKind::Struct(..)
|
||||||
|
| ExprKind::Tup(_)
|
||||||
|
| ExprKind::Type(..)
|
||||||
|
| ExprKind::Err(_) => PREC_UNAMBIGUOUS,
|
||||||
|
|
||||||
ExprKind::DropTemps(ref expr, ..) => expr.precedence(),
|
ExprKind::DropTemps(ref expr, ..) => expr.precedence(),
|
||||||
ExprKind::If(..) => ExprPrecedence::If,
|
|
||||||
ExprKind::Let(..) => ExprPrecedence::Let,
|
|
||||||
ExprKind::Loop(..) => ExprPrecedence::Loop,
|
|
||||||
ExprKind::Match(..) => ExprPrecedence::Match,
|
|
||||||
ExprKind::Closure { .. } => ExprPrecedence::Closure,
|
|
||||||
ExprKind::Block(..) => ExprPrecedence::Block,
|
|
||||||
ExprKind::Assign(..) => ExprPrecedence::Assign,
|
|
||||||
ExprKind::AssignOp(..) => ExprPrecedence::AssignOp,
|
|
||||||
ExprKind::Field(..) => ExprPrecedence::Field,
|
|
||||||
ExprKind::Index(..) => ExprPrecedence::Index,
|
|
||||||
ExprKind::Path(..) => ExprPrecedence::Path,
|
|
||||||
ExprKind::AddrOf(..) => ExprPrecedence::AddrOf,
|
|
||||||
ExprKind::Break(..) => ExprPrecedence::Break,
|
|
||||||
ExprKind::Continue(..) => ExprPrecedence::Continue,
|
|
||||||
ExprKind::Ret(..) => ExprPrecedence::Ret,
|
|
||||||
ExprKind::Become(..) => ExprPrecedence::Become,
|
|
||||||
ExprKind::Struct(..) => ExprPrecedence::Struct,
|
|
||||||
ExprKind::Repeat(..) => ExprPrecedence::Repeat,
|
|
||||||
ExprKind::Yield(..) => ExprPrecedence::Yield,
|
|
||||||
ExprKind::Type(..) | ExprKind::InlineAsm(..) | ExprKind::OffsetOf(..) => {
|
|
||||||
ExprPrecedence::Mac
|
|
||||||
}
|
|
||||||
ExprKind::Err(_) => ExprPrecedence::Err,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1015,7 +1015,7 @@ impl<'a> State<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_expr_maybe_paren(&mut self, expr: &hir::Expr<'_>, prec: i8) {
|
fn print_expr_maybe_paren(&mut self, expr: &hir::Expr<'_>, prec: i8) {
|
||||||
self.print_expr_cond_paren(expr, expr.precedence().order() < prec)
|
self.print_expr_cond_paren(expr, expr.precedence() < prec)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Prints an expr using syntax that's acceptable in a condition position, such as the `cond` in
|
/// Prints an expr using syntax that's acceptable in a condition position, such as the `cond` in
|
||||||
|
@ -1049,7 +1049,7 @@ impl<'a> State<'a> {
|
||||||
}
|
}
|
||||||
self.space();
|
self.space();
|
||||||
self.word_space("=");
|
self.word_space("=");
|
||||||
let npals = || parser::needs_par_as_let_scrutinee(init.precedence().order());
|
let npals = || parser::needs_par_as_let_scrutinee(init.precedence());
|
||||||
self.print_expr_cond_paren(init, Self::cond_needs_par(init) || npals())
|
self.print_expr_cond_paren(init, Self::cond_needs_par(init) || npals())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -606,7 +606,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Ok(rest_snippet) = rest_snippet {
|
if let Ok(rest_snippet) = rest_snippet {
|
||||||
let sugg = if callee_expr.precedence().order() >= PREC_UNAMBIGUOUS {
|
let sugg = if callee_expr.precedence() >= PREC_UNAMBIGUOUS {
|
||||||
vec![
|
vec![
|
||||||
(up_to_rcvr_span, "".to_string()),
|
(up_to_rcvr_span, "".to_string()),
|
||||||
(rest_span, format!(".{}({rest_snippet}", segment.ident)),
|
(rest_span, format!(".{}({rest_snippet}", segment.ident)),
|
||||||
|
|
|
@ -1107,7 +1107,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lossy_provenance_ptr2int_lint(&self, fcx: &FnCtxt<'a, 'tcx>, t_c: ty::cast::IntTy) {
|
fn lossy_provenance_ptr2int_lint(&self, fcx: &FnCtxt<'a, 'tcx>, t_c: ty::cast::IntTy) {
|
||||||
let expr_prec = self.expr.precedence().order();
|
let expr_prec = self.expr.precedence();
|
||||||
let needs_parens = expr_prec < rustc_ast::util::parser::PREC_UNAMBIGUOUS;
|
let needs_parens = expr_prec < rustc_ast::util::parser::PREC_UNAMBIGUOUS;
|
||||||
|
|
||||||
let needs_cast = !matches!(t_c, ty::cast::IntTy::U(ty::UintTy::Usize));
|
let needs_cast = !matches!(t_c, ty::cast::IntTy::U(ty::UintTy::Usize));
|
||||||
|
|
|
@ -2,7 +2,7 @@ use core::cmp::min;
|
||||||
use core::iter;
|
use core::iter;
|
||||||
|
|
||||||
use hir::def_id::LocalDefId;
|
use hir::def_id::LocalDefId;
|
||||||
use rustc_ast::util::parser::{ExprPrecedence, PREC_UNAMBIGUOUS};
|
use rustc_ast::util::parser::PREC_UNAMBIGUOUS;
|
||||||
use rustc_data_structures::packed::Pu128;
|
use rustc_data_structures::packed::Pu128;
|
||||||
use rustc_errors::{Applicability, Diag, MultiSpan};
|
use rustc_errors::{Applicability, Diag, MultiSpan};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
|
@ -398,7 +398,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
// so we remove the user's `clone` call.
|
// so we remove the user's `clone` call.
|
||||||
{
|
{
|
||||||
vec![(receiver_method.ident.span, conversion_method.name.to_string())]
|
vec![(receiver_method.ident.span, conversion_method.name.to_string())]
|
||||||
} else if expr.precedence().order() < ExprPrecedence::MethodCall.order() {
|
} else if expr.precedence() < PREC_UNAMBIGUOUS {
|
||||||
vec![
|
vec![
|
||||||
(expr.span.shrink_to_lo(), "(".to_string()),
|
(expr.span.shrink_to_lo(), "(".to_string()),
|
||||||
(expr.span.shrink_to_hi(), format!(").{}()", conversion_method.name)),
|
(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 span = expr.span.find_oldest_ancestor_in_same_ctxt();
|
||||||
|
|
||||||
let mut sugg = if expr.precedence().order() >= PREC_UNAMBIGUOUS {
|
let mut sugg = if expr.precedence() >= PREC_UNAMBIGUOUS {
|
||||||
vec![(span.shrink_to_hi(), ".into()".to_owned())]
|
vec![(span.shrink_to_hi(), ".into()".to_owned())]
|
||||||
} else {
|
} else {
|
||||||
vec![
|
vec![
|
||||||
|
@ -2985,7 +2985,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
"change the type of the numeric literal from `{checked_ty}` to `{expected_ty}`",
|
"change the type of the numeric literal from `{checked_ty}` to `{expected_ty}`",
|
||||||
);
|
);
|
||||||
|
|
||||||
let close_paren = if expr.precedence().order() < PREC_UNAMBIGUOUS {
|
let close_paren = if expr.precedence() < PREC_UNAMBIGUOUS {
|
||||||
sugg.push((expr.span.shrink_to_lo(), "(".to_string()));
|
sugg.push((expr.span.shrink_to_lo(), "(".to_string()));
|
||||||
")"
|
")"
|
||||||
} else {
|
} else {
|
||||||
|
@ -3010,7 +3010,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
let len = src.trim_end_matches(&checked_ty.to_string()).len();
|
let len = src.trim_end_matches(&checked_ty.to_string()).len();
|
||||||
expr.span.with_lo(expr.span.lo() + BytePos(len as u32))
|
expr.span.with_lo(expr.span.lo() + BytePos(len as u32))
|
||||||
},
|
},
|
||||||
if expr.precedence().order() < PREC_UNAMBIGUOUS {
|
if expr.precedence() < PREC_UNAMBIGUOUS {
|
||||||
// Readd `)`
|
// Readd `)`
|
||||||
format!("{expected_ty})")
|
format!("{expected_ty})")
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
use rustc_ast::mut_visit::{self, MutVisitor};
|
use rustc_ast::mut_visit::{self, MutVisitor};
|
||||||
use rustc_ast::ptr::P;
|
use rustc_ast::ptr::P;
|
||||||
use rustc_ast::token::{self, BinOpToken, Delimiter, IdentIsRaw, Token};
|
use rustc_ast::token::{self, BinOpToken, Delimiter, IdentIsRaw, Token};
|
||||||
|
use rustc_ast::util::parser::AssocOp;
|
||||||
use rustc_ast::visit::{self, Visitor};
|
use rustc_ast::visit::{self, Visitor};
|
||||||
use rustc_ast::{
|
use rustc_ast::{
|
||||||
self as ast, Arm, AttrVec, BinOpKind, BindingMode, ByRef, Expr, ExprKind, ExprPrecedence,
|
self as ast, Arm, AttrVec, BinOpKind, BindingMode, ByRef, Expr, ExprKind, LocalKind, MacCall,
|
||||||
LocalKind, MacCall, Mutability, Pat, PatField, PatFieldsRest, PatKind, Path, QSelf, RangeEnd,
|
Mutability, Pat, PatField, PatFieldsRest, PatKind, Path, QSelf, RangeEnd, RangeSyntax, Stmt,
|
||||||
RangeSyntax, Stmt, StmtKind,
|
StmtKind,
|
||||||
};
|
};
|
||||||
use rustc_ast_pretty::pprust;
|
use rustc_ast_pretty::pprust;
|
||||||
use rustc_errors::{Applicability, Diag, DiagArgValue, PResult, StashKey};
|
use rustc_errors::{Applicability, Diag, DiagArgValue, PResult, StashKey};
|
||||||
|
@ -458,7 +459,7 @@ impl<'a> Parser<'a> {
|
||||||
.create_err(UnexpectedExpressionInPattern {
|
.create_err(UnexpectedExpressionInPattern {
|
||||||
span,
|
span,
|
||||||
is_bound,
|
is_bound,
|
||||||
expr_precedence: expr.precedence().order(),
|
expr_precedence: expr.precedence(),
|
||||||
})
|
})
|
||||||
.stash(span, StashKey::ExprInPat)
|
.stash(span, StashKey::ExprInPat)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
|
@ -545,7 +546,8 @@ impl<'a> Parser<'a> {
|
||||||
let expr = match &err.args["expr_precedence"] {
|
let expr = match &err.args["expr_precedence"] {
|
||||||
DiagArgValue::Number(expr_precedence) => {
|
DiagArgValue::Number(expr_precedence) => {
|
||||||
if *expr_precedence
|
if *expr_precedence
|
||||||
<= ExprPrecedence::Binary(BinOpKind::Eq).order() as i32
|
<= AssocOp::from_ast_binop(BinOpKind::Eq).precedence()
|
||||||
|
as i32
|
||||||
{
|
{
|
||||||
format!("({expr})")
|
format!("({expr})")
|
||||||
} else {
|
} else {
|
||||||
|
@ -568,8 +570,9 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
Some(guard) => {
|
Some(guard) => {
|
||||||
// Are parentheses required around the old guard?
|
// Are parentheses required around the old guard?
|
||||||
let wrap_guard = guard.precedence().order()
|
let wrap_guard = guard.precedence()
|
||||||
<= ExprPrecedence::Binary(BinOpKind::And).order();
|
<= AssocOp::from_ast_binop(BinOpKind::And).precedence()
|
||||||
|
as i8;
|
||||||
|
|
||||||
err.subdiagnostic(
|
err.subdiagnostic(
|
||||||
UnexpectedExpressionInPatternSugg::UpdateGuard {
|
UnexpectedExpressionInPatternSugg::UpdateGuard {
|
||||||
|
|
|
@ -959,7 +959,7 @@ fn report<'tcx>(
|
||||||
// expr_str (the suggestion) is never shown if is_final_ufcs is true, since it's
|
// 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.kind == ExprKind::Call`. Therefore, this is, afaik, always unnecessary.
|
||||||
/*
|
/*
|
||||||
expr_str = if !expr_is_macro_call && is_final_ufcs && expr.precedence().order() < PREC_PREFIX {
|
expr_str = if !expr_is_macro_call && is_final_ufcs && expr.precedence() < PREC_PREFIX {
|
||||||
Cow::Owned(format!("({expr_str})"))
|
Cow::Owned(format!("({expr_str})"))
|
||||||
} else {
|
} else {
|
||||||
expr_str
|
expr_str
|
||||||
|
@ -999,7 +999,7 @@ fn report<'tcx>(
|
||||||
Node::Expr(e) => match e.kind {
|
Node::Expr(e) => match e.kind {
|
||||||
ExprKind::Call(callee, _) if callee.hir_id != data.first_expr.hir_id => (0, false),
|
ExprKind::Call(callee, _) if callee.hir_id != data.first_expr.hir_id => (0, false),
|
||||||
ExprKind::Call(..) => (PREC_UNAMBIGUOUS, matches!(expr.kind, ExprKind::Field(..))),
|
ExprKind::Call(..) => (PREC_UNAMBIGUOUS, matches!(expr.kind, ExprKind::Field(..))),
|
||||||
_ => (e.precedence().order(), false),
|
_ => (e.precedence(), false),
|
||||||
},
|
},
|
||||||
_ => (0, false),
|
_ => (0, false),
|
||||||
};
|
};
|
||||||
|
@ -1012,7 +1012,7 @@ fn report<'tcx>(
|
||||||
);
|
);
|
||||||
|
|
||||||
let sugg = if !snip_is_macro
|
let sugg = if !snip_is_macro
|
||||||
&& (calls_field || expr.precedence().order() < precedence)
|
&& (calls_field || expr.precedence() < precedence)
|
||||||
&& !has_enclosing_paren(&snip)
|
&& !has_enclosing_paren(&snip)
|
||||||
&& !is_in_tuple
|
&& !is_in_tuple
|
||||||
{
|
{
|
||||||
|
@ -1067,7 +1067,7 @@ fn report<'tcx>(
|
||||||
let (snip, snip_is_macro) =
|
let (snip, snip_is_macro) =
|
||||||
snippet_with_context(cx, expr.span, data.first_expr.span.ctxt(), "..", &mut app);
|
snippet_with_context(cx, expr.span, data.first_expr.span.ctxt(), "..", &mut app);
|
||||||
let sugg =
|
let sugg =
|
||||||
if !snip_is_macro && expr.precedence().order() < precedence && !has_enclosing_paren(&snip) {
|
if !snip_is_macro && expr.precedence() < precedence && !has_enclosing_paren(&snip) {
|
||||||
format!("{prefix}({snip})")
|
format!("{prefix}({snip})")
|
||||||
} else {
|
} else {
|
||||||
format!("{prefix}{snip}")
|
format!("{prefix}{snip}")
|
||||||
|
@ -1154,7 +1154,7 @@ impl<'tcx> Dereferencing<'tcx> {
|
||||||
},
|
},
|
||||||
Some(parent) if !parent.span.from_expansion() => {
|
Some(parent) if !parent.span.from_expansion() => {
|
||||||
// Double reference might be needed at this point.
|
// Double reference might be needed at this point.
|
||||||
if parent.precedence().order() == PREC_UNAMBIGUOUS {
|
if parent.precedence() == PREC_UNAMBIGUOUS {
|
||||||
// Parentheses would be needed here, don't lint.
|
// Parentheses would be needed here, don't lint.
|
||||||
*outer_pat = None;
|
*outer_pat = None;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -84,7 +84,7 @@ pub(super) fn check<'tcx>(
|
||||||
if !prefix.is_empty()
|
if !prefix.is_empty()
|
||||||
&& (
|
&& (
|
||||||
// Precedence of internal expression is less than or equal to precedence of `&expr`.
|
// Precedence of internal expression is less than or equal to precedence of `&expr`.
|
||||||
arg_expression.precedence().order() <= PREC_PREFIX || is_range_literal(arg_expression)
|
arg_expression.precedence() <= PREC_PREFIX || is_range_literal(arg_expression)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
arg_snip = format!("({arg_snip})").into();
|
arg_snip = format!("({arg_snip})").into();
|
||||||
|
|
|
@ -117,7 +117,7 @@ where
|
||||||
// it's being passed by value.
|
// it's being passed by value.
|
||||||
let scrutinee = peel_hir_expr_refs(scrutinee).0;
|
let scrutinee = peel_hir_expr_refs(scrutinee).0;
|
||||||
let (scrutinee_str, _) = snippet_with_context(cx, scrutinee.span, expr_ctxt, "..", &mut app);
|
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().order() < PREC_UNAMBIGUOUS {
|
let scrutinee_str = if scrutinee.span.eq_ctxt(expr.span) && scrutinee.precedence() < PREC_UNAMBIGUOUS {
|
||||||
format!("({scrutinee_str})")
|
format!("({scrutinee_str})")
|
||||||
} else {
|
} else {
|
||||||
scrutinee_str.into()
|
scrutinee_str.into()
|
||||||
|
|
|
@ -58,7 +58,7 @@ fn check_mul(cx: &LateContext<'_>, span: Span, lit: &Expr<'_>, exp: &Expr<'_>) {
|
||||||
{
|
{
|
||||||
let mut applicability = Applicability::MachineApplicable;
|
let mut applicability = Applicability::MachineApplicable;
|
||||||
let (snip, from_macro) = snippet_with_context(cx, exp.span, span.ctxt(), "..", &mut applicability);
|
let (snip, from_macro) = snippet_with_context(cx, exp.span, span.ctxt(), "..", &mut applicability);
|
||||||
let suggestion = if !from_macro && exp.precedence().order() < PREC_PREFIX && !has_enclosing_paren(&snip) {
|
let suggestion = if !from_macro && exp.precedence() < PREC_PREFIX && !has_enclosing_paren(&snip) {
|
||||||
format!("-({snip})")
|
format!("-({snip})")
|
||||||
} else {
|
} else {
|
||||||
format!("-{snip}")
|
format!("-{snip}")
|
||||||
|
|
|
@ -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 (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 (indexed_ty, indexed_ref_count) = peel_middle_ty_refs(cx.typeck_results().expr_ty(indexed));
|
||||||
let parent_expr = get_parent_expr(cx, expr);
|
let parent_expr = get_parent_expr(cx, expr);
|
||||||
let needs_parens_for_prefix = parent_expr.is_some_and(|parent| parent.precedence().order() > PREC_PREFIX);
|
let needs_parens_for_prefix = parent_expr.is_some_and(|parent| parent.precedence() > PREC_PREFIX);
|
||||||
|
|
||||||
if expr_ty == indexed_ty {
|
if expr_ty == indexed_ty {
|
||||||
if expr_ref_count > indexed_ref_count {
|
if expr_ref_count > indexed_ref_count {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use super::TRANSMUTES_EXPRESSIBLE_AS_PTR_CASTS;
|
use super::TRANSMUTES_EXPRESSIBLE_AS_PTR_CASTS;
|
||||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||||
use clippy_utils::sugg::Sugg;
|
use clippy_utils::sugg::Sugg;
|
||||||
use rustc_ast::ExprPrecedence;
|
use rustc_ast::util::parser::AssocOp;
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_hir::{Expr, Node};
|
use rustc_hir::{Expr, Node};
|
||||||
use rustc_hir_typeck::cast::check_cast;
|
use rustc_hir_typeck::cast::check_cast;
|
||||||
|
@ -44,7 +44,7 @@ pub(super) fn check<'tcx>(
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Node::Expr(parent) = cx.tcx.parent_hir_node(e.hir_id)
|
if let Node::Expr(parent) = cx.tcx.parent_hir_node(e.hir_id)
|
||||||
&& parent.precedence().order() > ExprPrecedence::Cast.order()
|
&& parent.precedence() > AssocOp::As.precedence() as i8
|
||||||
{
|
{
|
||||||
sugg = format!("({sugg})");
|
sugg = format!("({sugg})");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue