From cb362afcf26b9a09e8d96aaa10abb72d781a20df Mon Sep 17 00:00:00 2001 From: "Guillem L. Jara" <4lon3ly0@tutanota.com> Date: Fri, 15 May 2026 14:57:33 +0200 Subject: [PATCH] parser: bind places to assignments --- parser/src/pratt.rs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/parser/src/pratt.rs b/parser/src/pratt.rs index 35a31fe..9ce7b4f 100644 --- a/parser/src/pratt.rs +++ b/parser/src/pratt.rs @@ -78,10 +78,19 @@ impl<'a, 'b> Pratt<'a, 'b> { let place = Place::lower_from(lhs.take(), lex.span())?; Expr::node(op.expr(place), self.parser.arena) } else if let Ok(op) = BinaryPlaceOperator::parse(next, &span) { - if op.binding_power().0 < min_bp { - break; - } - let place = Place::lower_from(lhs.take(), lex.span())?; + // Places consume assignment operators with maximum precedence; + // effectively ignoring the enclosing operator's precedence. + // For example, `1 && x = 1` parses as `1 && (x = 1)`. + let place = match Place::lower_from(lhs.take(), lex.span()) { + Ok(x) => x, + Err((expr, _)) => { + lhs = expr; + if op.binding_power().0 < min_bp { + break; + } + return Err(ParsingError::OperatorExpectsVariable(lex.span())); + } + }; self.parse_place_op(lex, op, place)? } else if let Ok(op) = BinaryOperator::parse(next, &span) && !matches!(next, Token::Increment | Token::Decrement)