Skip to content

Commit

Permalink
Merge pull request #1785 from dtolnay/attrprecedence
Browse files Browse the repository at this point in the history
Lower the precedence of expressions containing outer attrs
  • Loading branch information
dtolnay authored Nov 29, 2024
2 parents ee6cd5d + 204c155 commit 1cf735e
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 3 deletions.
54 changes: 51 additions & 3 deletions src/precedence.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
#[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::{ExprBreak, ExprReturn, ExprYield};
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;
Expand Down Expand Up @@ -82,11 +89,21 @@ impl Precedence {

#[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(..) => Precedence::Unambiguous,
ReturnType::Type(..) => prefix_attrs(&e.attrs),
},

#[cfg(feature = "full")]
Expand All @@ -104,6 +121,36 @@ impl Precedence {
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(_)
Expand All @@ -130,9 +177,10 @@ impl Precedence {
| Expr::TryBlock(_)
| Expr::Tuple(_)
| Expr::Unsafe(_)
| Expr::Verbatim(_)
| Expr::While(_) => Precedence::Unambiguous,

Expr::Verbatim(_) => Precedence::Unambiguous,

#[cfg(not(feature = "full"))]
Expr::Break(_) | Expr::Closure(_) | Expr::Return(_) | Expr::Yield(_) => unreachable!(),
}
Expand Down
1 change: 1 addition & 0 deletions tests/test_expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -702,6 +702,7 @@ fn test_fixup() {
quote! { (..) += () },
quote! { (1 < 2) == (3 < 4) },
quote! { { (let _ = ()) } },
quote! { (#[attr] thing).field },
] {
let original: Expr = syn::parse2(tokens).unwrap();

Expand Down

0 comments on commit 1cf735e

Please sign in to comment.