- // Checks if `let` is in an invalid position like `let x = let y = 1;` or
- // if the current `let` is in a let_chains context but nested in another
- // expression like `if let Some(_) = _opt && [1, 2, 3][let _ = ()] = 1`.
- //
- // This method expects that the current token is `let`.
- fn manage_let_chains_context(&mut self) {
- debug_assert!(matches!(self.token.kind, TokenKind::Ident(kw::Let, _)));
- let is_in_a_let_chains_context_but_nested_in_other_expr = self.let_expr_allowed
- && !matches!(
- self.prev_token.kind,
- TokenKind::AndAnd | TokenKind::Ident(kw::If, _) | TokenKind::Ident(kw::While, _)
- );
- if !self.let_expr_allowed || is_in_a_let_chains_context_but_nested_in_other_expr {
+ /// Parses a `let $pat = $expr` pseudo-expression.
+ fn parse_let_expr(&mut self, attrs: AttrVec) -> PResult<'a, P<Expr>> {
+ // This is a *approximate* heuristic that detects if `let` chains are
+ // being parsed in the right position. It's approximate because it
+ // doesn't deny all invalid `let` expressions, just completely wrong usages.
+ let not_in_chain = !matches!(
+ self.prev_token.kind,
+ TokenKind::AndAnd | TokenKind::Ident(kw::If, _) | TokenKind::Ident(kw::While, _)
+ );
+ if !self.restrictions.contains(Restrictions::ALLOW_LET) || not_in_chain {