diff --git a/src/expr.rs b/src/expr.rs index 9493822f5a..80a4b1a1e0 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -3253,30 +3253,12 @@ pub(crate) mod printing { }; // These cases require parenthesization independently of precedence. - match (&*e.left, &e.op) { + if let BinOp::Lt(_) | BinOp::Shl(_) = &e.op { // `x as i32 < y` has the parser thinking that `i32 < y` is the // beginning of a path type. It starts trying to parse `x as (i32 < // y ...` instead of `(x as i32) < ...`. We need to convince it // _not_ to do that. - (_, BinOp::Lt(_) | BinOp::Shl(_)) if classify::confusable_with_adjacent_lt(&e.left) => { - left_needs_group = true; - } - - // We are given `(let _ = a) OP b`. - // - // - When `OP <= LAnd` we should print `let _ = a OP b` to avoid - // redundant parens as the parser will interpret this as `(let _ = - // a) OP b`. - // - // - Otherwise, e.g. when we have `(let a = b) < c` in AST, parens - // are required since the parser would interpret `let a = b < c` - // as `let a = (b < c)`. To achieve this, we force parens. - #[cfg(feature = "full")] - (Expr::Let(_), _) if binop_prec > Precedence::And => { - left_needs_group = true; - } - - _ => {} + left_needs_group |= classify::confusable_with_adjacent_lt(&e.left); } print_subexpression( diff --git a/src/fixup.rs b/src/fixup.rs index ddee906fb5..536da4e499 100644 --- a/src/fixup.rs +++ b/src/fixup.rs @@ -239,7 +239,7 @@ impl FixupContext { /// "let chain". pub fn needs_group_as_let_scrutinee(self, expr: &Expr) -> bool { self.parenthesize_exterior_struct_lit && classify::confusable_with_adjacent_block(expr) - || self.trailing_precedence(expr) <= Precedence::And + || self.trailing_precedence(expr) < Precedence::Let } /// Determines the effective precedence of a left subexpression. Some @@ -265,7 +265,11 @@ impl FixupContext { match expr { // Increase precedence of expressions that extend to the end of // current statement or group. - Expr::Break(_) | Expr::Closure(_) | Expr::Return(_) | Expr::Yield(_) => { + Expr::Break(_) + | Expr::Closure(_) + | Expr::Let(_) + | Expr::Return(_) + | Expr::Yield(_) => { return Precedence::Prefix; } Expr::Range(e) if e.start.is_none() => return Precedence::Prefix, diff --git a/src/precedence.rs b/src/precedence.rs index 354ea90812..1a26f195db 100644 --- a/src/precedence.rs +++ b/src/precedence.rs @@ -19,6 +19,9 @@ pub(crate) enum Precedence { Or, // && And, + // let + #[cfg(feature = "printing")] + Let, // == != < > <= >= Compare, // | @@ -97,8 +100,9 @@ impl Precedence { 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::Let(_) | Expr::Reference(_) | Expr::Unary(_) => Precedence::Prefix, + Expr::Reference(_) | Expr::Unary(_) => Precedence::Prefix, Expr::Array(_) | Expr::Async(_)