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