@@ -43,7 +43,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
4343 // FIXME(60707): Consider removing hack with principled solution.
4444 self . check_expr_has_type_or_error ( scrut, self . tcx . types . bool , |_| { } )
4545 } else {
46- self . demand_scrutinee_type ( arms, scrut )
46+ self . demand_scrutinee_type ( scrut , arms_contain_ref_bindings ( arms) , arms . is_empty ( ) )
4747 } ;
4848
4949 // If there are no arms, that is a diverging match; a special case.
@@ -98,7 +98,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
9898 self . diverges . set ( Diverges :: Maybe ) ;
9999 match g {
100100 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 ) ;
102110 }
103111 } ;
104112 }
@@ -450,8 +458,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
450458
451459 fn demand_scrutinee_type (
452460 & self ,
453- arms : & ' tcx [ hir:: Arm < ' tcx > ] ,
454461 scrut : & ' tcx hir:: Expr < ' tcx > ,
462+ contains_ref_bindings : Option < hir:: Mutability > ,
463+ no_arms : bool ,
455464 ) -> Ty < ' tcx > {
456465 // Not entirely obvious: if matches may create ref bindings, we want to
457466 // use the *precise* type of the scrutinee, *not* some supertype, as
@@ -505,17 +514,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
505514 // (once introduced) is populated by the time we get here.
506515 //
507516 // 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-
516517 if let Some ( m) = contains_ref_bindings {
517518 self . check_expr_with_needs ( scrut, Needs :: maybe_mut_place ( m) )
518- } else if arms . is_empty ( ) {
519+ } else if no_arms {
519520 self . check_expr ( scrut)
520521 } else {
521522 // ...but otherwise we want to use any supertype of the
@@ -546,3 +547,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
546547 }
547548 }
548549}
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