@@ -40,6 +40,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
40
40
temp_scope_override : Option < region:: Scope > ,
41
41
break_scope : region:: Scope ,
42
42
variable_source_info : SourceInfo ,
43
+ declare_bindings : bool ,
43
44
) -> BlockAnd < ( ) > {
44
45
let this = self ;
45
46
let expr = & this. thir [ expr_id] ;
@@ -53,6 +54,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
53
54
temp_scope_override,
54
55
break_scope,
55
56
variable_source_info,
57
+ declare_bindings,
56
58
) ) ;
57
59
58
60
let rhs_then_block = unpack ! ( this. then_else_break(
@@ -61,6 +63,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
61
63
temp_scope_override,
62
64
break_scope,
63
65
variable_source_info,
66
+ declare_bindings,
64
67
) ) ;
65
68
66
69
rhs_then_block. unit ( )
@@ -75,6 +78,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
75
78
temp_scope_override,
76
79
local_scope,
77
80
variable_source_info,
81
+ true ,
78
82
)
79
83
} ) ;
80
84
let rhs_success_block = unpack ! ( this. then_else_break(
@@ -83,6 +87,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
83
87
temp_scope_override,
84
88
break_scope,
85
89
variable_source_info,
90
+ true ,
86
91
) ) ;
87
92
this. cfg . goto ( lhs_success_block, variable_source_info, rhs_success_block) ;
88
93
rhs_success_block. unit ( )
@@ -102,6 +107,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
102
107
temp_scope_override,
103
108
local_scope,
104
109
variable_source_info,
110
+ true ,
105
111
)
106
112
} ) ;
107
113
this. break_for_else ( success_block, break_scope, variable_source_info) ;
@@ -116,6 +122,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
116
122
temp_scope_override,
117
123
break_scope,
118
124
variable_source_info,
125
+ declare_bindings,
119
126
)
120
127
} )
121
128
}
@@ -125,6 +132,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
125
132
temp_scope_override,
126
133
break_scope,
127
134
variable_source_info,
135
+ declare_bindings,
128
136
) ,
129
137
ExprKind :: Let { expr, ref pat } => this. lower_let_expr (
130
138
block,
@@ -133,7 +141,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
133
141
break_scope,
134
142
Some ( variable_source_info. scope ) ,
135
143
variable_source_info. span ,
136
- true ,
144
+ declare_bindings ,
137
145
) ,
138
146
_ => {
139
147
let temp_scope = temp_scope_override. unwrap_or_else ( || this. local_scope ( ) ) ;
@@ -737,13 +745,40 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
737
745
) ;
738
746
} ,
739
747
) ;
740
- if let Some ( Guard :: IfLet ( guard_pat, _) ) = guard {
741
- // FIXME: pass a proper `opt_match_place`
742
- self . declare_bindings ( visibility_scope, scope_span, guard_pat, None , None ) ;
748
+ if let Some ( & Guard :: If ( guard_expr) ) = guard {
749
+ self . declare_guard_bindings ( guard_expr, scope_span, visibility_scope) ;
743
750
}
744
751
visibility_scope
745
752
}
746
753
754
+ /// Declare bindings in a guard. This has to be done when declaring bindings
755
+ /// for an arm to ensure that or patterns only have one version of each
756
+ /// variable.
757
+ pub ( crate ) fn declare_guard_bindings (
758
+ & mut self ,
759
+ guard_expr : ExprId ,
760
+ scope_span : Span ,
761
+ visibility_scope : Option < SourceScope > ,
762
+ ) {
763
+ match self . thir . exprs [ guard_expr] . kind {
764
+ ExprKind :: Let { expr : _, pat : ref guard_pat } => {
765
+ // FIXME: pass a proper `opt_match_place`
766
+ self . declare_bindings ( visibility_scope, scope_span, guard_pat, None , None ) ;
767
+ }
768
+ ExprKind :: Scope { value, .. } => {
769
+ self . declare_guard_bindings ( value, scope_span, visibility_scope) ;
770
+ }
771
+ ExprKind :: Use { source } => {
772
+ self . declare_guard_bindings ( source, scope_span, visibility_scope) ;
773
+ }
774
+ ExprKind :: LogicalOp { op : LogicalOp :: And , lhs, rhs } => {
775
+ self . declare_guard_bindings ( lhs, scope_span, visibility_scope) ;
776
+ self . declare_guard_bindings ( rhs, scope_span, visibility_scope) ;
777
+ }
778
+ _ => { }
779
+ }
780
+ }
781
+
747
782
pub ( crate ) fn storage_live_binding (
748
783
& mut self ,
749
784
block : BasicBlock ,
@@ -2043,6 +2078,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
2043
2078
None ,
2044
2079
match_scope,
2045
2080
this. source_info ( arm. span ) ,
2081
+ false ,
2046
2082
)
2047
2083
}
2048
2084
Guard :: IfLet ( ref pat, s) => {
0 commit comments