@@ -84,6 +84,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
8484 break_scope,
8585 Some ( variable_source_info. scope ) ,
8686 variable_source_info. span ,
87+ true ,
8788 ) ,
8889 _ => {
8990 let temp_scope = temp_scope_override. unwrap_or_else ( || this. local_scope ( ) ) ;
@@ -357,7 +358,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
357358 None ,
358359 arm. span ,
359360 & arm. pattern ,
360- ArmHasGuard ( arm. guard . is_some ( ) ) ,
361+ arm. guard . as_ref ( ) ,
361362 opt_scrutinee_place,
362363 ) ;
363364
@@ -645,7 +646,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
645646 mut visibility_scope : Option < SourceScope > ,
646647 scope_span : Span ,
647648 pattern : & Pat < ' tcx > ,
648- has_guard : ArmHasGuard ,
649+ guard : Option < & Guard < ' tcx > > ,
649650 opt_match_place : Option < ( Option < & Place < ' tcx > > , Span ) > ,
650651 ) -> Option < SourceScope > {
651652 self . visit_primary_bindings (
@@ -667,12 +668,16 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
667668 var,
668669 ty,
669670 user_ty,
670- has_guard ,
671+ ArmHasGuard ( guard . is_some ( ) ) ,
671672 opt_match_place. map ( |( x, y) | ( x. cloned ( ) , y) ) ,
672673 pattern. span ,
673674 ) ;
674675 } ,
675676 ) ;
677+ if let Some ( Guard :: IfLet ( guard_pat, _) ) = guard {
678+ // FIXME: pass a proper `opt_match_place`
679+ self . declare_bindings ( visibility_scope, scope_span, guard_pat, None , None ) ;
680+ }
676681 visibility_scope
677682 }
678683
@@ -1766,6 +1771,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
17661771// Pat binding - used for `let` and function parameters as well.
17671772
17681773impl < ' a , ' tcx > Builder < ' a , ' tcx > {
1774+ /// If the bindings have already been declared, set `declare_bindings` to
1775+ /// `false` to avoid duplicated bindings declaration. Used for if-let guards.
17691776 pub ( crate ) fn lower_let_expr (
17701777 & mut self ,
17711778 mut block : BasicBlock ,
@@ -1774,6 +1781,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
17741781 else_target : region:: Scope ,
17751782 source_scope : Option < SourceScope > ,
17761783 span : Span ,
1784+ declare_bindings : bool ,
17771785 ) -> BlockAnd < ( ) > {
17781786 let expr_span = expr. span ;
17791787 let expr_place_builder = unpack ! ( block = self . lower_scrutinee( block, expr, expr_span) ) ;
@@ -1797,13 +1805,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
17971805 let otherwise_post_guard_block = otherwise_candidate. pre_binding_block . unwrap ( ) ;
17981806 self . break_for_else ( otherwise_post_guard_block, else_target, self . source_info ( expr_span) ) ;
17991807
1800- self . declare_bindings (
1801- source_scope,
1802- pat. span . to ( span) ,
1803- pat,
1804- ArmHasGuard ( false ) ,
1805- opt_expr_place,
1806- ) ;
1808+ if declare_bindings {
1809+ self . declare_bindings ( source_scope, pat. span . to ( span) , pat, None , opt_expr_place) ;
1810+ }
18071811
18081812 let post_guard_block = self . bind_pattern (
18091813 self . source_info ( pat. span ) ,
@@ -1984,7 +1988,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
19841988 Guard :: IfLet ( ref pat, scrutinee) => {
19851989 let s = & this. thir [ scrutinee] ;
19861990 guard_span = s. span ;
1987- this. lower_let_expr ( block, s, pat, match_scope, None , arm. span )
1991+ this. lower_let_expr ( block, s, pat, match_scope, None , arm. span , false )
19881992 }
19891993 } ) ;
19901994
0 commit comments