@@ -43,7 +43,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
43
43
// FIXME(60707): Consider removing hack with principled solution.
44
44
self . check_expr_has_type_or_error ( scrut, self . tcx . types . bool , |_| { } )
45
45
} else {
46
- self . demand_scrutinee_type ( arms, scrut )
46
+ self . demand_scrutinee_type ( scrut , arms_contain_ref_bindings ( arms) , arms . is_empty ( ) )
47
47
} ;
48
48
49
49
// If there are no arms, that is a diverging match; a special case.
@@ -98,7 +98,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
98
98
self . diverges . set ( Diverges :: Maybe ) ;
99
99
match g {
100
100
hir:: Guard :: If ( e) => {
101
- self . check_expr_has_type_or_error ( e, tcx. types . bool , |_| { } )
101
+ self . check_expr_has_type_or_error ( e, tcx. types . bool , |_| { } ) ;
102
+ }
103
+ hir:: Guard :: IfLet ( pat, e) => {
104
+ let scrutinee_ty = self . demand_scrutinee_type (
105
+ e,
106
+ pat. contains_explicit_ref_binding ( ) ,
107
+ false ,
108
+ ) ;
109
+ self . check_pat_top ( & pat, scrutinee_ty, None , true ) ;
102
110
}
103
111
} ;
104
112
}
@@ -450,8 +458,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
450
458
451
459
fn demand_scrutinee_type (
452
460
& self ,
453
- arms : & ' tcx [ hir:: Arm < ' tcx > ] ,
454
461
scrut : & ' tcx hir:: Expr < ' tcx > ,
462
+ contains_ref_bindings : Option < hir:: Mutability > ,
463
+ no_arms : bool ,
455
464
) -> Ty < ' tcx > {
456
465
// Not entirely obvious: if matches may create ref bindings, we want to
457
466
// use the *precise* type of the scrutinee, *not* some supertype, as
@@ -505,17 +514,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
505
514
// (once introduced) is populated by the time we get here.
506
515
//
507
516
// See #44848.
508
- let contains_ref_bindings = arms
509
- . iter ( )
510
- . filter_map ( |a| a. pat . contains_explicit_ref_binding ( ) )
511
- . max_by_key ( |m| match * m {
512
- hir:: Mutability :: Mut => 1 ,
513
- hir:: Mutability :: Not => 0 ,
514
- } ) ;
515
-
516
517
if let Some ( m) = contains_ref_bindings {
517
518
self . check_expr_with_needs ( scrut, Needs :: maybe_mut_place ( m) )
518
- } else if arms . is_empty ( ) {
519
+ } else if no_arms {
519
520
self . check_expr ( scrut)
520
521
} else {
521
522
// ...but otherwise we want to use any supertype of the
@@ -546,3 +547,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
546
547
}
547
548
}
548
549
}
550
+
551
+ fn arms_contain_ref_bindings ( arms : & ' tcx [ hir:: Arm < ' tcx > ] ) -> Option < hir:: Mutability > {
552
+ arms. iter ( ) . filter_map ( |a| a. pat . contains_explicit_ref_binding ( ) ) . max_by_key ( |m| match * m {
553
+ hir:: Mutability :: Mut => 1 ,
554
+ hir:: Mutability :: Not => 0 ,
555
+ } )
556
+ }
0 commit comments