summaryrefslogtreecommitdiff
path: root/rust/syn/precedence.rs
diff options
context:
space:
mode:
authorMiguel Ojeda <ojeda@kernel.org>2025-11-24 18:18:27 +0300
committerMiguel Ojeda <ojeda@kernel.org>2025-11-24 19:15:44 +0300
commit808c999fc9e7c366fd47da564e69d579c1dc8279 (patch)
treed81985de64150acef12e038e98ef950e1b41b2d6 /rust/syn/precedence.rs
parent88de91cc1ce7b3069ccabc1a5fbe16d41c663093 (diff)
downloadlinux-808c999fc9e7c366fd47da564e69d579c1dc8279.tar.xz
rust: syn: import crate
This is a subset of the Rust `syn` crate, version 2.0.106 (released 2025-08-16), licensed under "Apache-2.0 OR MIT", from: https://github.com/dtolnay/syn/raw/2.0.106/src The files are copied as-is, with no modifications whatsoever (not even adding the SPDX identifiers). For copyright details, please see: https://github.com/dtolnay/syn/blob/2.0.106/README.md#license https://github.com/dtolnay/syn/blob/2.0.106/LICENSE-APACHE https://github.com/dtolnay/syn/blob/2.0.106/LICENSE-MIT The next two patches modify these files as needed for use within the kernel. This patch split allows reviewers to double-check the import and to clearly see the differences introduced. The following script may be used to verify the contents: for path in $(cd rust/syn/ && find . -type f -name '*.rs'); do curl --silent --show-error --location \ https://github.com/dtolnay/syn/raw/2.0.106/src/$path \ | diff --unified rust/syn/$path - && echo $path: OK done Reviewed-by: Gary Guo <gary@garyguo.net> Tested-by: Gary Guo <gary@garyguo.net> Tested-by: Jesung Yang <y.j3ms.n@gmail.com> Link: https://patch.msgid.link/20251124151837.2184382-16-ojeda@kernel.org Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
Diffstat (limited to 'rust/syn/precedence.rs')
-rw-r--r--rust/syn/precedence.rs210
1 files changed, 210 insertions, 0 deletions
diff --git a/rust/syn/precedence.rs b/rust/syn/precedence.rs
new file mode 100644
index 000000000000..1891bfc202fd
--- /dev/null
+++ b/rust/syn/precedence.rs
@@ -0,0 +1,210 @@
+#[cfg(all(feature = "printing", feature = "full"))]
+use crate::attr::{AttrStyle, Attribute};
+#[cfg(feature = "printing")]
+use crate::expr::Expr;
+#[cfg(all(feature = "printing", feature = "full"))]
+use crate::expr::{
+ ExprArray, ExprAsync, ExprAwait, ExprBlock, ExprBreak, ExprCall, ExprConst, ExprContinue,
+ ExprField, ExprForLoop, ExprGroup, ExprIf, ExprIndex, ExprInfer, ExprLit, ExprLoop, ExprMacro,
+ ExprMatch, ExprMethodCall, ExprParen, ExprPath, ExprRepeat, ExprReturn, ExprStruct, ExprTry,
+ ExprTryBlock, ExprTuple, ExprUnsafe, ExprWhile, ExprYield,
+};
+use crate::op::BinOp;
+#[cfg(all(feature = "printing", feature = "full"))]
+use crate::ty::ReturnType;
+use std::cmp::Ordering;
+
+// Reference: https://doc.rust-lang.org/reference/expressions.html#expression-precedence
+pub(crate) enum Precedence {
+ // return, break, closures
+ Jump,
+ // = += -= *= /= %= &= |= ^= <<= >>=
+ Assign,
+ // .. ..=
+ Range,
+ // ||
+ Or,
+ // &&
+ And,
+ // let
+ #[cfg(feature = "printing")]
+ Let,
+ // == != < > <= >=
+ Compare,
+ // |
+ BitOr,
+ // ^
+ BitXor,
+ // &
+ BitAnd,
+ // << >>
+ Shift,
+ // + -
+ Sum,
+ // * / %
+ Product,
+ // as
+ Cast,
+ // unary - * ! & &mut
+ #[cfg(feature = "printing")]
+ Prefix,
+ // paths, loops, function calls, array indexing, field expressions, method calls
+ #[cfg(feature = "printing")]
+ Unambiguous,
+}
+
+impl Precedence {
+ pub(crate) const MIN: Self = Precedence::Jump;
+
+ pub(crate) fn of_binop(op: &BinOp) -> Self {
+ match op {
+ BinOp::Add(_) | BinOp::Sub(_) => Precedence::Sum,
+ BinOp::Mul(_) | BinOp::Div(_) | BinOp::Rem(_) => Precedence::Product,
+ BinOp::And(_) => Precedence::And,
+ BinOp::Or(_) => Precedence::Or,
+ BinOp::BitXor(_) => Precedence::BitXor,
+ BinOp::BitAnd(_) => Precedence::BitAnd,
+ BinOp::BitOr(_) => Precedence::BitOr,
+ BinOp::Shl(_) | BinOp::Shr(_) => Precedence::Shift,
+
+ BinOp::Eq(_)
+ | BinOp::Lt(_)
+ | BinOp::Le(_)
+ | BinOp::Ne(_)
+ | BinOp::Ge(_)
+ | BinOp::Gt(_) => Precedence::Compare,
+
+ BinOp::AddAssign(_)
+ | BinOp::SubAssign(_)
+ | BinOp::MulAssign(_)
+ | BinOp::DivAssign(_)
+ | BinOp::RemAssign(_)
+ | BinOp::BitXorAssign(_)
+ | BinOp::BitAndAssign(_)
+ | BinOp::BitOrAssign(_)
+ | BinOp::ShlAssign(_)
+ | BinOp::ShrAssign(_) => Precedence::Assign,
+ }
+ }
+
+ #[cfg(feature = "printing")]
+ pub(crate) fn of(e: &Expr) -> Self {
+ #[cfg(feature = "full")]
+ fn prefix_attrs(attrs: &[Attribute]) -> Precedence {
+ for attr in attrs {
+ if let AttrStyle::Outer = attr.style {
+ return Precedence::Prefix;
+ }
+ }
+ Precedence::Unambiguous
+ }
+
+ match e {
+ #[cfg(feature = "full")]
+ Expr::Closure(e) => match e.output {
+ ReturnType::Default => Precedence::Jump,
+ ReturnType::Type(..) => prefix_attrs(&e.attrs),
+ },
+
+ #[cfg(feature = "full")]
+ Expr::Break(ExprBreak { expr, .. })
+ | Expr::Return(ExprReturn { expr, .. })
+ | Expr::Yield(ExprYield { expr, .. }) => match expr {
+ Some(_) => Precedence::Jump,
+ None => Precedence::Unambiguous,
+ },
+
+ Expr::Assign(_) => Precedence::Assign,
+ Expr::Range(_) => Precedence::Range,
+ Expr::Binary(e) => Precedence::of_binop(&e.op),
+ Expr::Let(_) => Precedence::Let,
+ Expr::Cast(_) => Precedence::Cast,
+ Expr::RawAddr(_) | Expr::Reference(_) | Expr::Unary(_) => Precedence::Prefix,
+
+ #[cfg(feature = "full")]
+ Expr::Array(ExprArray { attrs, .. })
+ | Expr::Async(ExprAsync { attrs, .. })
+ | Expr::Await(ExprAwait { attrs, .. })
+ | Expr::Block(ExprBlock { attrs, .. })
+ | Expr::Call(ExprCall { attrs, .. })
+ | Expr::Const(ExprConst { attrs, .. })
+ | Expr::Continue(ExprContinue { attrs, .. })
+ | Expr::Field(ExprField { attrs, .. })
+ | Expr::ForLoop(ExprForLoop { attrs, .. })
+ | Expr::Group(ExprGroup { attrs, .. })
+ | Expr::If(ExprIf { attrs, .. })
+ | Expr::Index(ExprIndex { attrs, .. })
+ | Expr::Infer(ExprInfer { attrs, .. })
+ | Expr::Lit(ExprLit { attrs, .. })
+ | Expr::Loop(ExprLoop { attrs, .. })
+ | Expr::Macro(ExprMacro { attrs, .. })
+ | Expr::Match(ExprMatch { attrs, .. })
+ | Expr::MethodCall(ExprMethodCall { attrs, .. })
+ | Expr::Paren(ExprParen { attrs, .. })
+ | Expr::Path(ExprPath { attrs, .. })
+ | Expr::Repeat(ExprRepeat { attrs, .. })
+ | Expr::Struct(ExprStruct { attrs, .. })
+ | Expr::Try(ExprTry { attrs, .. })
+ | Expr::TryBlock(ExprTryBlock { attrs, .. })
+ | Expr::Tuple(ExprTuple { attrs, .. })
+ | Expr::Unsafe(ExprUnsafe { attrs, .. })
+ | Expr::While(ExprWhile { attrs, .. }) => prefix_attrs(attrs),
+
+ #[cfg(not(feature = "full"))]
+ Expr::Array(_)
+ | Expr::Async(_)
+ | Expr::Await(_)
+ | Expr::Block(_)
+ | Expr::Call(_)
+ | Expr::Const(_)
+ | Expr::Continue(_)
+ | Expr::Field(_)
+ | Expr::ForLoop(_)
+ | Expr::Group(_)
+ | Expr::If(_)
+ | Expr::Index(_)
+ | Expr::Infer(_)
+ | Expr::Lit(_)
+ | Expr::Loop(_)
+ | Expr::Macro(_)
+ | Expr::Match(_)
+ | Expr::MethodCall(_)
+ | Expr::Paren(_)
+ | Expr::Path(_)
+ | Expr::Repeat(_)
+ | Expr::Struct(_)
+ | Expr::Try(_)
+ | Expr::TryBlock(_)
+ | Expr::Tuple(_)
+ | Expr::Unsafe(_)
+ | Expr::While(_) => Precedence::Unambiguous,
+
+ Expr::Verbatim(_) => Precedence::Unambiguous,
+
+ #[cfg(not(feature = "full"))]
+ Expr::Break(_) | Expr::Closure(_) | Expr::Return(_) | Expr::Yield(_) => unreachable!(),
+ }
+ }
+}
+
+impl Copy for Precedence {}
+
+impl Clone for Precedence {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+
+impl PartialEq for Precedence {
+ fn eq(&self, other: &Self) -> bool {
+ *self as u8 == *other as u8
+ }
+}
+
+impl PartialOrd for Precedence {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ let this = *self as u8;
+ let other = *other as u8;
+ Some(this.cmp(&other))
+ }
+}