@@ -25,6 +25,7 @@ use rustc_macros::Subdiagnostic;
2525use rustc_session:: errors:: { ExprParenthesesNeeded , report_lit_error} ;
2626use rustc_session:: lint:: BuiltinLintDiag ;
2727use rustc_session:: lint:: builtin:: BREAK_WITH_LABEL_AND_LOOP ;
28+ use rustc_span:: edition:: Edition ;
2829use rustc_span:: source_map:: { self , Spanned } ;
2930use rustc_span:: symbol:: { Ident , Symbol , kw, sym} ;
3031use rustc_span:: { BytePos , ErrorGuaranteed , Pos , Span } ;
@@ -2486,7 +2487,7 @@ impl<'a> Parser<'a> {
24862487 /// Parses an `if` expression (`if` token already eaten).
24872488 fn parse_expr_if ( & mut self ) -> PResult < ' a , P < Expr > > {
24882489 let lo = self . prev_token . span ;
2489- let cond = self . parse_expr_cond ( ) ?;
2490+ let cond = self . parse_expr_cond ( lo . edition ( ) ) ?;
24902491 self . parse_if_after_cond ( lo, cond)
24912492 }
24922493
@@ -2595,7 +2596,7 @@ impl<'a> Parser<'a> {
25952596 }
25962597
25972598 /// Parses the condition of a `if` or `while` expression.
2598- fn parse_expr_cond ( & mut self ) -> PResult < ' a , P < Expr > > {
2599+ fn parse_expr_cond ( & mut self , edition : Edition ) -> PResult < ' a , P < Expr > > {
25992600 let attrs = self . parse_outer_attributes ( ) ?;
26002601 let ( mut cond, _) =
26012602 self . parse_expr_res ( Restrictions :: NO_STRUCT_LITERAL | Restrictions :: ALLOW_LET , attrs) ?;
@@ -2605,6 +2606,27 @@ impl<'a> Parser<'a> {
26052606 if let ExprKind :: Let ( _, _, _, Recovered :: No ) = cond. kind {
26062607 // Remove the last feature gating of a `let` expression since it's stable.
26072608 self . psess . gated_spans . ungate_last ( sym:: let_chains, cond. span ) ;
2609+ } else {
2610+ fn ungate_let_exprs ( this : & mut Parser < ' _ > , expr : & Expr ) {
2611+ if !expr. span . at_least_rust_2024 ( ) {
2612+ return ;
2613+ }
2614+ match & expr. kind {
2615+ ExprKind :: Binary ( BinOp { node : BinOpKind :: And , .. } , lhs, rhs) => {
2616+ ungate_let_exprs ( this, rhs) ;
2617+ ungate_let_exprs ( this, lhs) ;
2618+ }
2619+ ExprKind :: Let ( ..) => {
2620+ this. psess . gated_spans . ungate_last ( sym:: let_chains, expr. span )
2621+ }
2622+ _ => ( ) ,
2623+ }
2624+ }
2625+ if edition. at_least_rust_2024 ( ) {
2626+ // Scoping code checks the top level edition of the `if`: let's match it here.
2627+ // Also check all editions in between, just to make sure.
2628+ ungate_let_exprs ( self , & cond) ;
2629+ }
26082630 }
26092631
26102632 Ok ( cond)
@@ -2889,7 +2911,7 @@ impl<'a> Parser<'a> {
28892911
28902912 /// Parses a `while` or `while let` expression (`while` token already eaten).
28912913 fn parse_expr_while ( & mut self , opt_label : Option < Label > , lo : Span ) -> PResult < ' a , P < Expr > > {
2892- let cond = self . parse_expr_cond ( ) . map_err ( |mut err| {
2914+ let cond = self . parse_expr_cond ( lo . edition ( ) ) . map_err ( |mut err| {
28932915 err. span_label ( lo, "while parsing the condition of this `while` expression" ) ;
28942916 err
28952917 } ) ?;
0 commit comments