@@ -4392,20 +4392,17 @@ impl<'a> LoweringContext<'a> {
4392
4392
let then_blk = self . lower_block ( then, false ) ;
4393
4393
let then_expr = self . expr_block ( then_blk, ThinVec :: new ( ) ) ;
4394
4394
let ( then_pats, scrutinee, desugar) = match cond. node {
4395
- // `<pat> => <then>`
4395
+ // `<pat> => <then>`:
4396
4396
ExprKind :: Let ( ref pats, ref scrutinee) => {
4397
4397
let scrutinee = self . lower_expr ( scrutinee) ;
4398
4398
let pats = pats. iter ( ) . map ( |pat| self . lower_pat ( pat) ) . collect ( ) ;
4399
4399
let desugar = hir:: MatchSource :: IfLetDesugar { contains_else_clause } ;
4400
4400
( pats, scrutinee, desugar)
4401
4401
}
4402
- // `true => then`:
4402
+ // `true => < then> `:
4403
4403
_ => {
4404
4404
// Lower condition:
4405
4405
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`.
4409
4406
let span_block = self . mark_span_with_reason ( CondTemporary , cond. span , None ) ;
4410
4407
// Wrap in a construct equivalent to `{ let _t = $cond; _t }`
4411
4408
// to preserve drop semantics since `if cond { ... }` does not
@@ -4422,61 +4419,36 @@ impl<'a> LoweringContext<'a> {
4422
4419
hir:: ExprKind :: Match ( P ( scrutinee) , vec ! [ then_arm, else_arm] . into ( ) , desugar)
4423
4420
}
4424
4421
// 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.
4447
4425
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
+ } ;
4468
4432
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
+ _ => {
4480
4452
// We desugar: `'label: while $cond $body` into:
4481
4453
//
4482
4454
// ```
@@ -4488,40 +4460,37 @@ impl<'a> LoweringContext<'a> {
4488
4460
// }
4489
4461
// ```
4490
4462
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
-
4502
4463
// Lower condition:
4503
- let span_block = this. mark_span_with_reason ( CondTemporary , cond. span , None ) ;
4504
4464
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 ) ;
4505
4466
// 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
4507
4468
// let temporaries live outside of `cond`.
4508
4469
let cond = this. expr_drop_temps ( span_block, P ( cond) , ThinVec :: new ( ) ) ;
4509
4470
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) ) ;
4516
4478
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
+ } ) ,
4525
4494
ExprKind :: Loop ( ref body, opt_label) => self . with_loop_scope ( e. id , |this| {
4526
4495
hir:: ExprKind :: Loop (
4527
4496
this. lower_block ( body, false ) ,
0 commit comments