@@ -109,13 +109,99 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
109109 )
110110 ) ;
111111 }
112+ StmtKind :: Let {
113+ remainder_scope,
114+ init_scope,
115+ pattern,
116+ initializer : Some ( initializer) ,
117+ lint_level,
118+ else_block : Some ( else_block) ,
119+ } => {
120+ let ignores_expr_result = matches ! ( pattern. kind, PatKind :: Wild ) ;
121+ this. block_context . push ( BlockFrame :: Statement { ignores_expr_result } ) ;
122+ // This place is not really used because this destination place
123+ // should never be used to take values at the end of the failure
124+ // block.
125+ let else_block_span = this. thir [ * else_block] . span ;
126+ let dummy_place = this. temp ( this. tcx . types . never , else_block_span) ;
127+ let failure_entry = this. cfg . start_new_block ( ) ;
128+ let failure_block;
129+ unpack ! (
130+ failure_block = this. ast_block(
131+ dummy_place,
132+ failure_entry,
133+ * else_block,
134+ this. source_info( else_block_span) ,
135+ )
136+ ) ;
137+ this. cfg . terminate (
138+ failure_block,
139+ this. source_info ( else_block_span) ,
140+ TerminatorKind :: Unreachable ,
141+ ) ;
142+
143+ // Declare the bindings, which may create a source scope.
144+ let remainder_span = remainder_scope. span ( this. tcx , this. region_scope_tree ) ;
145+ this. push_scope ( ( * remainder_scope, source_info) ) ;
146+ let_scope_stack. push ( remainder_scope) ;
147+
148+ let visibility_scope =
149+ Some ( this. new_source_scope ( remainder_span, LintLevel :: Inherited , None ) ) ;
150+
151+ let init = & this. thir [ * initializer] ;
152+ let initializer_span = init. span ;
153+ this. declare_bindings (
154+ visibility_scope,
155+ remainder_span,
156+ pattern,
157+ ArmHasGuard ( false ) ,
158+ Some ( ( None , initializer_span) ) ,
159+ ) ;
160+ this. visit_primary_bindings (
161+ pattern,
162+ UserTypeProjections :: none ( ) ,
163+ & mut |this, _, _, _, node, span, _, _| {
164+ this. storage_live_binding ( block, node, span, OutsideGuard , false ) ;
165+ } ,
166+ ) ;
167+ let failure = unpack ! (
168+ block = this. in_opt_scope(
169+ opt_destruction_scope. map( |de| ( de, source_info) ) ,
170+ |this| {
171+ let scope = ( * init_scope, source_info) ;
172+ this. in_scope( scope, * lint_level, |this| {
173+ this. ast_let_else(
174+ block,
175+ init,
176+ initializer_span,
177+ * else_block,
178+ & last_remainder_scope,
179+ pattern,
180+ )
181+ } )
182+ }
183+ )
184+ ) ;
185+ this. cfg . goto ( failure, source_info, failure_entry) ;
186+
187+ if let Some ( source_scope) = visibility_scope {
188+ this. source_scope = source_scope;
189+ }
190+ last_remainder_scope = * remainder_scope;
191+ }
192+ StmtKind :: Let { init_scope, initializer : None , else_block : Some ( _) , .. } => {
193+ span_bug ! (
194+ init_scope. span( this. tcx, this. region_scope_tree) ,
195+ "initializer is missing, but else block is present in this let binding" ,
196+ )
197+ }
112198 StmtKind :: Let {
113199 remainder_scope,
114200 init_scope,
115201 ref pattern,
116202 initializer,
117203 lint_level,
118- else_block,
204+ else_block : None ,
119205 } => {
120206 let ignores_expr_result = matches ! ( pattern. kind, PatKind :: Wild ) ;
121207 this. block_context . push ( BlockFrame :: Statement { ignores_expr_result } ) ;
@@ -141,27 +227,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
141227 |this| {
142228 let scope = ( * init_scope, source_info) ;
143229 this. in_scope( scope, * lint_level, |this| {
144- if let Some ( else_block) = else_block {
145- this. ast_let_else(
146- block,
147- init,
148- initializer_span,
149- * else_block,
150- visibility_scope,
151- last_remainder_scope,
152- remainder_span,
153- pattern,
154- )
155- } else {
156- this. declare_bindings(
157- visibility_scope,
158- remainder_span,
159- pattern,
160- ArmHasGuard ( false ) ,
161- Some ( ( None , initializer_span) ) ,
162- ) ;
163- this. expr_into_pattern( block, pattern, init) // irrefutable pattern
164- }
230+ this. declare_bindings(
231+ visibility_scope,
232+ remainder_span,
233+ pattern,
234+ ArmHasGuard ( false ) ,
235+ Some ( ( None , initializer_span) ) ,
236+ ) ;
237+ this. expr_into_pattern( block, & pattern, init) // irrefutable pattern
165238 } )
166239 } ,
167240 )
0 commit comments