File Index
Files and directories
Sign in
FILE

precedence.rs

File preview with syntax highlighting.

linux-6.19.14/rust/syn/precedence.rs RUST
  1// SPDX-License-Identifier: Apache-2.0 OR MIT
  2
  3#[cfg(all(feature = "printing", feature = "full"))]
  4use crate::attr::{AttrStyle, Attribute};
  5#[cfg(feature = "printing")]
  6use crate::expr::Expr;
  7#[cfg(all(feature = "printing", feature = "full"))]
  8use crate::expr::{
  9    ExprArray, ExprAsync, ExprAwait, ExprBlock, ExprBreak, ExprCall, ExprConst, ExprContinue,
 10    ExprField, ExprForLoop, ExprGroup, ExprIf, ExprIndex, ExprInfer, ExprLit, ExprLoop, ExprMacro,
 11    ExprMatch, ExprMethodCall, ExprParen, ExprPath, ExprRepeat, ExprReturn, ExprStruct, ExprTry,
 12    ExprTryBlock, ExprTuple, ExprUnsafe, ExprWhile, ExprYield,
 13};
 14use crate::op::BinOp;
 15#[cfg(all(feature = "printing", feature = "full"))]
 16use crate::ty::ReturnType;
 17use std::cmp::Ordering;
 18
 19// Reference: https://doc.rust-lang.org/reference/expressions.html#expression-precedence
 20pub(crate) enum Precedence {
 21    // return, break, closures
 22    Jump,
 23    // = += -= *= /= %= &= |= ^= <<= >>=
 24    Assign,
 25    // .. ..=
 26    Range,
 27    // ||
 28    Or,
 29    // &&
 30    And,
 31    // let
 32    #[cfg(feature = "printing")]
 33    Let,
 34    // == != < > <= >=
 35    Compare,
 36    // |
 37    BitOr,
 38    // ^
 39    BitXor,
 40    // &
 41    BitAnd,
 42    // << >>
 43    Shift,
 44    // + -
 45    Sum,
 46    // * / %
 47    Product,
 48    // as
 49    Cast,
 50    // unary - * ! & &mut
 51    #[cfg(feature = "printing")]
 52    Prefix,
 53    // paths, loops, function calls, array indexing, field expressions, method calls
 54    #[cfg(feature = "printing")]
 55    Unambiguous,
 56}
 57
 58impl Precedence {
 59    pub(crate) const MIN: Self = Precedence::Jump;
 60
 61    pub(crate) fn of_binop(op: &BinOp) -> Self {
 62        match op {
 63            BinOp::Add(_) | BinOp::Sub(_) => Precedence::Sum,
 64            BinOp::Mul(_) | BinOp::Div(_) | BinOp::Rem(_) => Precedence::Product,
 65            BinOp::And(_) => Precedence::And,
 66            BinOp::Or(_) => Precedence::Or,
 67            BinOp::BitXor(_) => Precedence::BitXor,
 68            BinOp::BitAnd(_) => Precedence::BitAnd,
 69            BinOp::BitOr(_) => Precedence::BitOr,
 70            BinOp::Shl(_) | BinOp::Shr(_) => Precedence::Shift,
 71
 72            BinOp::Eq(_)
 73            | BinOp::Lt(_)
 74            | BinOp::Le(_)
 75            | BinOp::Ne(_)
 76            | BinOp::Ge(_)
 77            | BinOp::Gt(_) => Precedence::Compare,
 78
 79            BinOp::AddAssign(_)
 80            | BinOp::SubAssign(_)
 81            | BinOp::MulAssign(_)
 82            | BinOp::DivAssign(_)
 83            | BinOp::RemAssign(_)
 84            | BinOp::BitXorAssign(_)
 85            | BinOp::BitAndAssign(_)
 86            | BinOp::BitOrAssign(_)
 87            | BinOp::ShlAssign(_)
 88            | BinOp::ShrAssign(_) => Precedence::Assign,
 89        }
 90    }
 91
 92    #[cfg(feature = "printing")]
 93    pub(crate) fn of(e: &Expr) -> Self {
 94        #[cfg(feature = "full")]
 95        fn prefix_attrs(attrs: &[Attribute]) -> Precedence {
 96            for attr in attrs {
 97                if let AttrStyle::Outer = attr.style {
 98                    return Precedence::Prefix;
 99                }
100            }
101            Precedence::Unambiguous
102        }
103
104        match e {
105            #[cfg(feature = "full")]
106            Expr::Closure(e) => match e.output {
107                ReturnType::Default => Precedence::Jump,
108                ReturnType::Type(..) => prefix_attrs(&e.attrs),
109            },
110
111            #[cfg(feature = "full")]
112            Expr::Break(ExprBreak { expr, .. })
113            | Expr::Return(ExprReturn { expr, .. })
114            | Expr::Yield(ExprYield { expr, .. }) => match expr {
115                Some(_) => Precedence::Jump,
116                None => Precedence::Unambiguous,
117            },
118
119            Expr::Assign(_) => Precedence::Assign,
120            Expr::Range(_) => Precedence::Range,
121            Expr::Binary(e) => Precedence::of_binop(&e.op),
122            Expr::Let(_) => Precedence::Let,
123            Expr::Cast(_) => Precedence::Cast,
124            Expr::RawAddr(_) | Expr::Reference(_) | Expr::Unary(_) => Precedence::Prefix,
125
126            #[cfg(feature = "full")]
127            Expr::Array(ExprArray { attrs, .. })
128            | Expr::Async(ExprAsync { attrs, .. })
129            | Expr::Await(ExprAwait { attrs, .. })
130            | Expr::Block(ExprBlock { attrs, .. })
131            | Expr::Call(ExprCall { attrs, .. })
132            | Expr::Const(ExprConst { attrs, .. })
133            | Expr::Continue(ExprContinue { attrs, .. })
134            | Expr::Field(ExprField { attrs, .. })
135            | Expr::ForLoop(ExprForLoop { attrs, .. })
136            | Expr::Group(ExprGroup { attrs, .. })
137            | Expr::If(ExprIf { attrs, .. })
138            | Expr::Index(ExprIndex { attrs, .. })
139            | Expr::Infer(ExprInfer { attrs, .. })
140            | Expr::Lit(ExprLit { attrs, .. })
141            | Expr::Loop(ExprLoop { attrs, .. })
142            | Expr::Macro(ExprMacro { attrs, .. })
143            | Expr::Match(ExprMatch { attrs, .. })
144            | Expr::MethodCall(ExprMethodCall { attrs, .. })
145            | Expr::Paren(ExprParen { attrs, .. })
146            | Expr::Path(ExprPath { attrs, .. })
147            | Expr::Repeat(ExprRepeat { attrs, .. })
148            | Expr::Struct(ExprStruct { attrs, .. })
149            | Expr::Try(ExprTry { attrs, .. })
150            | Expr::TryBlock(ExprTryBlock { attrs, .. })
151            | Expr::Tuple(ExprTuple { attrs, .. })
152            | Expr::Unsafe(ExprUnsafe { attrs, .. })
153            | Expr::While(ExprWhile { attrs, .. }) => prefix_attrs(attrs),
154
155            #[cfg(not(feature = "full"))]
156            Expr::Array(_)
157            | Expr::Async(_)
158            | Expr::Await(_)
159            | Expr::Block(_)
160            | Expr::Call(_)
161            | Expr::Const(_)
162            | Expr::Continue(_)
163            | Expr::Field(_)
164            | Expr::ForLoop(_)
165            | Expr::Group(_)
166            | Expr::If(_)
167            | Expr::Index(_)
168            | Expr::Infer(_)
169            | Expr::Lit(_)
170            | Expr::Loop(_)
171            | Expr::Macro(_)
172            | Expr::Match(_)
173            | Expr::MethodCall(_)
174            | Expr::Paren(_)
175            | Expr::Path(_)
176            | Expr::Repeat(_)
177            | Expr::Struct(_)
178            | Expr::Try(_)
179            | Expr::TryBlock(_)
180            | Expr::Tuple(_)
181            | Expr::Unsafe(_)
182            | Expr::While(_) => Precedence::Unambiguous,
183
184            Expr::Verbatim(_) => Precedence::Unambiguous,
185
186            #[cfg(not(feature = "full"))]
187            Expr::Break(_) | Expr::Closure(_) | Expr::Return(_) | Expr::Yield(_) => unreachable!(),
188        }
189    }
190}
191
192impl Copy for Precedence {}
193
194impl Clone for Precedence {
195    fn clone(&self) -> Self {
196        *self
197    }
198}
199
200impl PartialEq for Precedence {
201    fn eq(&self, other: &Self) -> bool {
202        *self as u8 == *other as u8
203    }
204}
205
206impl PartialOrd for Precedence {
207    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
208        let this = *self as u8;
209        let other = *other as u8;
210        Some(this.cmp(&other))
211    }
212}
~/ Read-only file preview.