@@ -84,6 +84,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
84
84
break_scope,
85
85
Some ( variable_source_info. scope ) ,
86
86
variable_source_info. span ,
87
+ true ,
87
88
) ,
88
89
_ => {
89
90
let temp_scope = temp_scope_override. unwrap_or_else ( || this. local_scope ( ) ) ;
@@ -357,7 +358,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
357
358
None ,
358
359
arm. span ,
359
360
& arm. pattern ,
360
- ArmHasGuard ( arm. guard . is_some ( ) ) ,
361
+ arm. guard . as_ref ( ) ,
361
362
opt_scrutinee_place,
362
363
) ;
363
364
@@ -645,7 +646,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
645
646
mut visibility_scope : Option < SourceScope > ,
646
647
scope_span : Span ,
647
648
pattern : & Pat < ' tcx > ,
648
- has_guard : ArmHasGuard ,
649
+ guard : Option < & Guard < ' tcx > > ,
649
650
opt_match_place : Option < ( Option < & Place < ' tcx > > , Span ) > ,
650
651
) -> Option < SourceScope > {
651
652
self . visit_primary_bindings (
@@ -667,12 +668,16 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
667
668
var,
668
669
ty,
669
670
user_ty,
670
- has_guard ,
671
+ ArmHasGuard ( guard . is_some ( ) ) ,
671
672
opt_match_place. map ( |( x, y) | ( x. cloned ( ) , y) ) ,
672
673
pattern. span ,
673
674
) ;
674
675
} ,
675
676
) ;
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
+ }
676
681
visibility_scope
677
682
}
678
683
@@ -1766,6 +1771,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1766
1771
// Pat binding - used for `let` and function parameters as well.
1767
1772
1768
1773
impl < ' 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.
1769
1776
pub ( crate ) fn lower_let_expr (
1770
1777
& mut self ,
1771
1778
mut block : BasicBlock ,
@@ -1774,6 +1781,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1774
1781
else_target : region:: Scope ,
1775
1782
source_scope : Option < SourceScope > ,
1776
1783
span : Span ,
1784
+ declare_bindings : bool ,
1777
1785
) -> BlockAnd < ( ) > {
1778
1786
let expr_span = expr. span ;
1779
1787
let expr_place_builder = unpack ! ( block = self . lower_scrutinee( block, expr, expr_span) ) ;
@@ -1797,13 +1805,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1797
1805
let otherwise_post_guard_block = otherwise_candidate. pre_binding_block . unwrap ( ) ;
1798
1806
self . break_for_else ( otherwise_post_guard_block, else_target, self . source_info ( expr_span) ) ;
1799
1807
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
+ }
1807
1811
1808
1812
let post_guard_block = self . bind_pattern (
1809
1813
self . source_info ( pat. span ) ,
@@ -1984,7 +1988,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
1984
1988
Guard :: IfLet ( ref pat, scrutinee) => {
1985
1989
let s = & this. thir [ scrutinee] ;
1986
1990
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 )
1988
1992
}
1989
1993
} ) ;
1990
1994
0 commit comments