From 96175bea89134a416dfd7f8db93a4c157187020a Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sun, 5 Jan 2025 21:08:07 -0800 Subject: [PATCH] Integrate Expr::Let into precedence fixups --- src/fixup.rs | 37 +++++++++++++++++++++++++++++++++++-- tests/test_expr.rs | 18 ++++++++++++++++-- 2 files changed, 51 insertions(+), 4 deletions(-) diff --git a/src/fixup.rs b/src/fixup.rs index e49f81131..b0973df25 100644 --- a/src/fixup.rs +++ b/src/fixup.rs @@ -357,7 +357,7 @@ impl FixupContext { } _ => default_prec <= self.previous_operator, } && match self.next_operator { - Precedence::Range => true, + Precedence::Range | Precedence::Or | Precedence::And => true, _ => !self.next_operator_can_begin_expr, } { if let Scan::Bailout | Scan::Fail = scan_right(expr, self, self.previous_operator, 1, 0) @@ -700,6 +700,37 @@ fn scan_right( Scan::Consume } } + Expr::Let(e) => { + if bailout_offset >= 1 { + return Scan::Consume; + } + let right_fixup = fixup.rightmost_subexpression_fixup(false, false, Precedence::Let); + let scan = scan_right( + &e.expr, + right_fixup, + Precedence::Let, + 1, + if fixup.next_operator < Precedence::Let { + 0 + } else { + 1 + }, + ); + match scan { + Scan::Fail | Scan::Bailout if fixup.next_operator < Precedence::Let => { + return Scan::Bailout; + } + Scan::Consume => return Scan::Consume, + _ => {} + } + if right_fixup.rightmost_subexpression_precedence(&e.expr) < Precedence::Let { + Scan::Consume + } else if let Scan::Fail = scan { + Scan::Bailout + } else { + Scan::Consume + } + } Expr::Array(_) | Expr::Async(_) | Expr::Await(_) @@ -714,7 +745,6 @@ fn scan_right( | Expr::If(_) | Expr::Index(_) | Expr::Infer(_) - | Expr::Let(_) | Expr::Lit(_) | Expr::Loop(_) | Expr::Macro(_) @@ -731,6 +761,9 @@ fn scan_right( | Expr::Verbatim(_) | Expr::While(_) => match fixup.next_operator { Precedence::Assign | Precedence::Range if precedence == Precedence::Range => Scan::Fail, + _ if precedence == Precedence::Let && fixup.next_operator < Precedence::Let => { + Scan::Fail + } _ => consume_by_precedence, }, } diff --git a/tests/test_expr.rs b/tests/test_expr.rs index 226c044db..67d5f0dd4 100644 --- a/tests/test_expr.rs +++ b/tests/test_expr.rs @@ -24,8 +24,8 @@ use syn::visit_mut::VisitMut as _; use syn::{ parse_quote, token, AngleBracketedGenericArguments, Arm, BinOp, Block, Expr, ExprArray, ExprAssign, ExprAsync, ExprAwait, ExprBinary, ExprBlock, ExprBreak, ExprCall, ExprCast, - ExprClosure, ExprConst, ExprContinue, ExprField, ExprForLoop, ExprIf, ExprIndex, ExprLit, - ExprLoop, ExprMacro, ExprMatch, ExprMethodCall, ExprPath, ExprRange, ExprRawAddr, + ExprClosure, ExprConst, ExprContinue, ExprField, ExprForLoop, ExprIf, ExprIndex, ExprLet, + ExprLit, ExprLoop, ExprMacro, ExprMatch, ExprMethodCall, ExprPath, ExprRange, ExprRawAddr, ExprReference, ExprReturn, ExprStruct, ExprTry, ExprTryBlock, ExprTuple, ExprUnary, ExprUnsafe, ExprWhile, ExprYield, GenericArgument, Label, Lifetime, Lit, LitInt, Macro, MacroDelimiter, Member, Pat, PatWild, Path, PathArguments, PathSegment, PointerMutability, QSelf, RangeLimits, @@ -1076,6 +1076,20 @@ fn test_permutations() -> ExitCode { })); }); + // Expr::Let + iter(depth, &mut |expr| { + f(Expr::Let(ExprLet { + attrs: Vec::new(), + let_token: Token![let](span), + pat: Box::new(Pat::Wild(PatWild { + attrs: Vec::new(), + underscore_token: Token![_](span), + })), + eq_token: Token![=](span), + expr: Box::new(expr), + })); + }); + // Expr::Range f(Expr::Range(ExprRange { // `..`