@@ -4392,20 +4392,17 @@ impl<'a> LoweringContext<'a> {
43924392 let then_blk = self . lower_block ( then, false ) ;
43934393 let then_expr = self . expr_block ( then_blk, ThinVec :: new ( ) ) ;
43944394 let ( then_pats, scrutinee, desugar) = match cond. node {
4395- // `<pat> => <then>`
4395+ // `<pat> => <then>`:
43964396 ExprKind :: Let ( ref pats, ref scrutinee) => {
43974397 let scrutinee = self . lower_expr ( scrutinee) ;
43984398 let pats = pats. iter ( ) . map ( |pat| self . lower_pat ( pat) ) . collect ( ) ;
43994399 let desugar = hir:: MatchSource :: IfLetDesugar { contains_else_clause } ;
44004400 ( pats, scrutinee, desugar)
44014401 }
4402- // `true => then`:
4402+ // `true => < then> `:
44034403 _ => {
44044404 // Lower condition:
44054405 let cond = self . lower_expr ( cond) ;
4406- // Wrap in a construct equivalent to `{ let _t = $cond; _t }`
4407- // to preserve drop semantics since `if cond { ... }`
4408- // don't let temporaries live outside of `cond`.
44094406 let span_block = self . mark_span_with_reason ( CondTemporary , cond. span , None ) ;
44104407 // Wrap in a construct equivalent to `{ let _t = $cond; _t }`
44114408 // to preserve drop semantics since `if cond { ... }` does not
@@ -4422,61 +4419,36 @@ impl<'a> LoweringContext<'a> {
44224419 hir:: ExprKind :: Match ( P ( scrutinee) , vec ! [ then_arm, else_arm] . into ( ) , desugar)
44234420 }
44244421 // FIXME(#53667): handle lowering of && and parens.
4425- ExprKind :: While ( ref cond, ref body, opt_label) => {
4426- // Desugar `ExprWhileLet`
4427- // from: `[opt_ident]: while let <pat> = <sub_expr> <body>`
4428- if let ExprKind :: Let ( ref pats, ref sub_expr) = cond. node {
4429- // to:
4430- //
4431- // [opt_ident]: loop {
4432- // match <sub_expr> {
4433- // <pat> => <body>,
4434- // _ => break
4435- // }
4436- // }
4437-
4438- // Note that the block AND the condition are evaluated in the loop scope.
4439- // This is done to allow `break` from inside the condition of the loop.
4440- let ( body, break_expr, sub_expr) = self . with_loop_scope ( e. id , |this| {
4441- (
4442- this. lower_block ( body, false ) ,
4443- this. expr_break ( e. span , ThinVec :: new ( ) ) ,
4444- this. with_loop_condition_scope ( |this| P ( this. lower_expr ( sub_expr) ) ) ,
4445- )
4446- } ) ;
4422+ ExprKind :: While ( ref cond, ref body, opt_label) => self . with_loop_scope ( e. id , |this| {
4423+ // Note that the block AND the condition are evaluated in the loop scope.
4424+ // This is done to allow `break` from inside the condition of the loop.
44474425
4448- // `<pat> => <body>`
4449- let pat_arm = {
4450- let body_expr = P ( self . expr_block ( body, ThinVec :: new ( ) ) ) ;
4451- let pats = pats. iter ( ) . map ( |pat| self . lower_pat ( pat) ) . collect ( ) ;
4452- self . arm ( pats, body_expr)
4453- } ;
4454-
4455- // `_ => break`
4456- let break_arm = {
4457- let pat_under = self . pat_wild ( e. span ) ;
4458- self . arm ( hir_vec ! [ pat_under] , break_expr)
4459- } ;
4460-
4461- // `match <sub_expr> { ... }`
4462- let match_expr = self . expr_match (
4463- sub_expr. span ,
4464- sub_expr,
4465- hir_vec ! [ pat_arm, break_arm] ,
4466- hir:: MatchSource :: WhileLetDesugar ,
4467- ) ;
4426+ // `_ => break`:
4427+ let else_arm = {
4428+ let else_pat = this. pat_wild ( e. span ) ;
4429+ let else_expr = this. expr_break ( e. span , ThinVec :: new ( ) ) ;
4430+ this. arm ( hir_vec ! [ else_pat] , else_expr)
4431+ } ;
44684432
4469- // `[opt_ident]: loop { ... }`
4470- let loop_block = P ( self . block_expr ( P ( match_expr) ) ) ;
4471- let loop_expr = hir:: ExprKind :: Loop (
4472- loop_block,
4473- self . lower_label ( opt_label) ,
4474- hir:: LoopSource :: WhileLet ,
4475- ) ;
4476- // Add attributes to the outer returned expr node.
4477- loop_expr
4478- } else {
4479- self . with_loop_scope ( e. id , |this| {
4433+ // Handle then + scrutinee:
4434+ let then_blk = this. lower_block ( body, false ) ;
4435+ let then_expr = this. expr_block ( then_blk, ThinVec :: new ( ) ) ;
4436+ let ( then_pats, scrutinee, desugar, source) = match cond. node {
4437+ ExprKind :: Let ( ref pats, ref scrutinee) => {
4438+ // to:
4439+ //
4440+ // [opt_ident]: loop {
4441+ // match <sub_expr> {
4442+ // <pat> => <body>,
4443+ // _ => break
4444+ // }
4445+ // }
4446+ let scrutinee = this. with_loop_condition_scope ( |t| t. lower_expr ( scrutinee) ) ;
4447+ let pats = pats. iter ( ) . map ( |pat| this. lower_pat ( pat) ) . collect ( ) ;
4448+ let desugar = hir:: MatchSource :: WhileLetDesugar ;
4449+ ( pats, scrutinee, desugar, hir:: LoopSource :: WhileLet )
4450+ }
4451+ _ => {
44804452 // We desugar: `'label: while $cond $body` into:
44814453 //
44824454 // ```
@@ -4488,40 +4460,37 @@ impl<'a> LoweringContext<'a> {
44884460 // }
44894461 // ```
44904462
4491- // `true => then`:
4492- let then_pat = this. pat_bool ( e. span , true ) ;
4493- let then_blk = this. lower_block ( body, false ) ;
4494- let then_expr = this. expr_block ( then_blk, ThinVec :: new ( ) ) ;
4495- let then_arm = this. arm ( hir_vec ! [ then_pat] , P ( then_expr) ) ;
4496-
4497- // `_ => break`:
4498- let else_pat = this. pat_wild ( e. span ) ;
4499- let else_expr = this. expr_break ( e. span , ThinVec :: new ( ) ) ;
4500- let else_arm = this. arm ( hir_vec ! [ else_pat] , else_expr) ;
4501-
45024463 // Lower condition:
4503- let span_block = this. mark_span_with_reason ( CondTemporary , cond. span , None ) ;
45044464 let cond = this. with_loop_condition_scope ( |this| this. lower_expr ( cond) ) ;
4465+ let span_block = this. mark_span_with_reason ( CondTemporary , cond. span , None ) ;
45054466 // Wrap in a construct equivalent to `{ let _t = $cond; _t }`
4506- // to preserve drop semantics since `if cond { ... }` does not
4467+ // to preserve drop semantics since `while cond { ... }` does not
45074468 // let temporaries live outside of `cond`.
45084469 let cond = this. expr_drop_temps ( span_block, P ( cond) , ThinVec :: new ( ) ) ;
45094470
4510- let match_expr = this. expr_match (
4511- cond. span ,
4512- P ( cond) ,
4513- vec ! [ then_arm, else_arm] . into ( ) ,
4514- hir:: MatchSource :: WhileDesugar ,
4515- ) ;
4471+ let desugar = hir:: MatchSource :: WhileDesugar ;
4472+ // `true => <then>`:
4473+ let pats = hir_vec ! [ this. pat_bool( e. span, true ) ] ;
4474+ ( pats, cond, desugar, hir:: LoopSource :: While )
4475+ }
4476+ } ;
4477+ let then_arm = this. arm ( then_pats, P ( then_expr) ) ;
45164478
4517- hir:: ExprKind :: Loop (
4518- P ( this. block_expr ( P ( match_expr) ) ) ,
4519- this. lower_label ( opt_label) ,
4520- hir:: LoopSource :: While ,
4521- )
4522- } )
4523- }
4524- }
4479+ // `match <scrutinee> { ... }`
4480+ let match_expr = this. expr_match (
4481+ scrutinee. span ,
4482+ P ( scrutinee) ,
4483+ hir_vec ! [ then_arm, else_arm] ,
4484+ desugar,
4485+ ) ;
4486+
4487+ // `[opt_ident]: loop { ... }`
4488+ hir:: ExprKind :: Loop (
4489+ P ( this. block_expr ( P ( match_expr) ) ) ,
4490+ this. lower_label ( opt_label) ,
4491+ source
4492+ )
4493+ } ) ,
45254494 ExprKind :: Loop ( ref body, opt_label) => self . with_loop_scope ( e. id , |this| {
45264495 hir:: ExprKind :: Loop (
45274496 this. lower_block ( body, false ) ,
0 commit comments