@@ -35,42 +35,48 @@ use std::convert::TryFrom;
3535use std:: mem;
3636
3737impl < ' a , ' tcx > Builder < ' a , ' tcx > {
38- pub ( crate ) fn then_else_blocks (
38+ pub ( crate ) fn then_else_break (
3939 & mut self ,
4040 mut block : BasicBlock ,
4141 expr : & Expr < ' tcx > ,
42- scope : region:: Scope ,
43- source_info : SourceInfo ,
44- ) -> ( BasicBlock , BasicBlock ) {
42+ temp_scope : region:: Scope ,
43+ break_scope : region:: Scope ,
44+ variable_scope_span : Span ,
45+ ) -> BlockAnd < ( ) > {
4546 let this = self ;
4647 let expr_span = expr. span ;
4748
4849 match expr. kind {
4950 ExprKind :: Scope { region_scope, lint_level, value } => {
50- let region_scope = ( region_scope, source_info) ;
51- let then_block ;
52- let else_block = unpack ! (
53- then_block = this . in_scope ( region_scope , lint_level , |this| {
54- let ( then_block , else_block ) =
55- this . then_else_blocks ( block , & this . thir [ value ] , scope , source_info ) ;
56- then_block . and ( else_block )
57- } )
58- ) ;
59- ( then_block , else_block )
51+ let region_scope = ( region_scope, this . source_info ( expr_span ) ) ;
52+ this . in_scope ( region_scope , lint_level , |this| {
53+ this . then_else_break (
54+ block ,
55+ & this . thir [ value ] ,
56+ temp_scope ,
57+ break_scope ,
58+ variable_scope_span ,
59+ )
60+ } )
6061 }
6162 ExprKind :: Let { expr, ref pat } => {
62- // FIXME: Use correct span.
63- this. lower_let ( block, & this. thir [ expr] , pat, expr_span)
63+ this. lower_let_expr ( block, & this. thir [ expr] , pat, break_scope, variable_scope_span)
6464 }
6565 _ => {
6666 let mutability = Mutability :: Mut ;
67- let place = unpack ! ( block = this. as_temp( block, Some ( scope) , expr, mutability) ) ;
67+ let place =
68+ unpack ! ( block = this. as_temp( block, Some ( temp_scope) , expr, mutability) ) ;
6869 let operand = Operand :: Move ( Place :: from ( place) ) ;
70+
6971 let then_block = this. cfg . start_new_block ( ) ;
7072 let else_block = this. cfg . start_new_block ( ) ;
7173 let term = TerminatorKind :: if_ ( this. tcx , operand, then_block, else_block) ;
74+
75+ let source_info = this. source_info ( expr_span) ;
7276 this. cfg . terminate ( block, source_info, term) ;
73- ( then_block, else_block)
77+ this. break_for_else ( else_block, break_scope, source_info) ;
78+
79+ then_block. unit ( )
7480 }
7581 }
7682 }
@@ -302,6 +308,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
302308
303309 let arm_source_info = self . source_info ( arm. span ) ;
304310 let arm_scope = ( arm. scope , arm_source_info) ;
311+ let match_scope = self . local_scope ( ) ;
305312 self . in_scope ( arm_scope, arm. lint_level , |this| {
306313 // `try_upvars_resolved` may fail if it is unable to resolve the given
307314 // `PlaceBuilder` inside a closure. In this case, we don't want to include
@@ -340,6 +347,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
340347 scrutinee_span,
341348 Some ( arm. span ) ,
342349 Some ( arm. scope ) ,
350+ Some ( match_scope) ,
343351 ) ;
344352
345353 if let Some ( source_scope) = scope {
@@ -384,6 +392,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
384392 scrutinee_span : Span ,
385393 arm_span : Option < Span > ,
386394 arm_scope : Option < region:: Scope > ,
395+ match_scope : Option < region:: Scope > ,
387396 ) -> BasicBlock {
388397 if candidate. subcandidates . is_empty ( ) {
389398 // Avoid generating another `BasicBlock` when we only have one
@@ -395,6 +404,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
395404 fake_borrow_temps,
396405 scrutinee_span,
397406 arm_span,
407+ match_scope,
398408 true ,
399409 )
400410 } else {
@@ -431,6 +441,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
431441 & fake_borrow_temps,
432442 scrutinee_span,
433443 arm_span,
444+ match_scope,
434445 schedule_drops,
435446 ) ;
436447 if arm_scope. is_none ( ) {
@@ -616,6 +627,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
616627 irrefutable_pat. span ,
617628 None ,
618629 None ,
630+ None ,
619631 )
620632 . unit ( )
621633 }
@@ -1742,13 +1754,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
17421754// Pat binding - used for `let` and function parameters as well.
17431755
17441756impl < ' a , ' tcx > Builder < ' a , ' tcx > {
1745- pub fn lower_let (
1757+ crate fn lower_let_expr (
17461758 & mut self ,
17471759 mut block : BasicBlock ,
17481760 expr : & Expr < ' tcx > ,
17491761 pat : & Pat < ' tcx > ,
1762+ else_target : region:: Scope ,
17501763 span : Span ,
1751- ) -> ( BasicBlock , BasicBlock ) {
1764+ ) -> BlockAnd < ( ) > {
17521765 let expr_span = expr. span ;
17531766 let expr_place_builder = unpack ! ( block = self . lower_scrutinee( block, expr, expr_span) ) ;
17541767 let mut guard_candidate = Candidate :: new ( expr_place_builder. clone ( ) , & pat, false ) ;
@@ -1769,6 +1782,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
17691782 expr_place = expr_builder. into_place ( self . tcx , self . typeck_results ) ;
17701783 opt_expr_place = Some ( ( Some ( & expr_place) , expr_span) ) ;
17711784 }
1785+ let otherwise_post_guard_block = otherwise_candidate. pre_binding_block . unwrap ( ) ;
1786+ self . break_for_else ( otherwise_post_guard_block, else_target, self . source_info ( expr_span) ) ;
1787+
17721788 self . declare_bindings ( None , pat. span . to ( span) , pat, ArmHasGuard ( false ) , opt_expr_place) ;
17731789 let post_guard_block = self . bind_pattern (
17741790 self . source_info ( pat. span ) ,
@@ -1778,9 +1794,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
17781794 expr. span ,
17791795 None ,
17801796 None ,
1797+ None ,
17811798 ) ;
1782- let otherwise_post_guard_block = otherwise_candidate . pre_binding_block . unwrap ( ) ;
1783- ( post_guard_block, otherwise_post_guard_block )
1799+
1800+ post_guard_block. unit ( )
17841801 }
17851802
17861803 /// Initializes each of the bindings from the candidate by
@@ -1799,6 +1816,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
17991816 fake_borrows : & Vec < ( Place < ' tcx > , Local ) > ,
18001817 scrutinee_span : Span ,
18011818 arm_span : Option < Span > ,
1819+ match_scope : Option < region:: Scope > ,
18021820 schedule_drops : bool ,
18031821 ) -> BasicBlock {
18041822 debug ! ( "bind_and_guard_matched_candidate(candidate={:?})" , candidate) ;
@@ -1929,17 +1947,25 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
19291947 self . cfg . push_assign ( block, scrutinee_source_info, Place :: from ( temp) , borrow) ;
19301948 }
19311949
1932- let ( guard_span, ( post_guard_block, otherwise_post_guard_block) ) = match * guard {
1933- Guard :: If ( e) => {
1934- let e = & self . thir [ e] ;
1935- let source_info = self . source_info ( e. span ) ;
1936- ( e. span , self . test_bool ( block, e, source_info) )
1937- }
1938- Guard :: IfLet ( ref pat, scrutinee) => {
1939- let s = & self . thir [ scrutinee] ;
1940- ( s. span , self . lower_let ( block, s, pat, arm_span. unwrap ( ) ) )
1941- }
1942- } ;
1950+ let arm_span = arm_span. unwrap ( ) ;
1951+ let arm_scope = self . local_scope ( ) ;
1952+ let match_scope = match_scope. unwrap ( ) ;
1953+ let mut guard_span = rustc_span:: DUMMY_SP ;
1954+
1955+ let ( post_guard_block, otherwise_post_guard_block) =
1956+ self . in_if_then_scope ( match_scope, |this| match * guard {
1957+ Guard :: If ( e) => {
1958+ let e = & this. thir [ e] ;
1959+ guard_span = e. span ;
1960+ this. then_else_break ( block, e, arm_scope, match_scope, arm_span)
1961+ }
1962+ Guard :: IfLet ( ref pat, scrutinee) => {
1963+ let s = & this. thir [ scrutinee] ;
1964+ guard_span = s. span ;
1965+ this. lower_let_expr ( block, s, pat, match_scope, arm_span)
1966+ }
1967+ } ) ;
1968+
19431969 let source_info = self . source_info ( guard_span) ;
19441970 let guard_end = self . source_info ( tcx. sess . source_map ( ) . end_point ( guard_span) ) ;
19451971 let guard_frame = self . guard_context . pop ( ) . unwrap ( ) ;
@@ -1955,10 +1981,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
19551981 self . cfg . terminate ( unreachable, source_info, TerminatorKind :: Unreachable ) ;
19561982 unreachable
19571983 } ) ;
1958- let outside_scope = self . cfg . start_new_block ( ) ;
1959- self . exit_top_scope ( otherwise_post_guard_block, outside_scope, source_info) ;
19601984 self . false_edges (
1961- outside_scope ,
1985+ otherwise_post_guard_block ,
19621986 otherwise_block,
19631987 candidate. next_candidate_pre_binding_block ,
19641988 source_info,
0 commit comments