@@ -21,7 +21,7 @@ use rustc::mir::*;
2121use rustc:: hir;
2222use hair:: * ;
2323use syntax:: ast:: { Name , NodeId } ;
24- use syntax_pos:: Span ;
24+ use syntax_pos:: { DUMMY_SP , Span } ;
2525
2626// helper functions, broken out by category:
2727mod simplify;
@@ -398,10 +398,12 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
398398 candidates. iter ( ) . take_while ( |c| c. match_pairs . is_empty ( ) ) . count ( ) ;
399399 debug ! ( "match_candidates: {:?} candidates fully matched" , fully_matched) ;
400400 let mut unmatched_candidates = candidates. split_off ( fully_matched) ;
401- for candidate in candidates {
401+ for ( index , candidate) in candidates. into_iter ( ) . enumerate ( ) {
402402 // If so, apply any bindings, test the guard (if any), and
403403 // branch to the arm.
404- if let Some ( b) = self . bind_and_guard_matched_candidate ( block, arm_blocks, candidate) {
404+ let is_last = index == fully_matched - 1 ;
405+ if let Some ( b) = self . bind_and_guard_matched_candidate ( block, arm_blocks,
406+ candidate, is_last) {
405407 block = b;
406408 } else {
407409 // if None is returned, then any remaining candidates
@@ -664,7 +666,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
664666 fn bind_and_guard_matched_candidate < ' pat > ( & mut self ,
665667 mut block : BasicBlock ,
666668 arm_blocks : & mut ArmBlocks ,
667- candidate : Candidate < ' pat , ' tcx > )
669+ candidate : Candidate < ' pat , ' tcx > ,
670+ is_last_arm : bool )
668671 -> Option < BasicBlock > {
669672 debug ! ( "bind_and_guard_matched_candidate(block={:?}, candidate={:?})" ,
670673 block, candidate) ;
@@ -685,10 +688,26 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
685688 self . cfg . terminate ( block, source_info,
686689 TerminatorKind :: if_ ( self . hir . tcx ( ) , cond, arm_block, otherwise) ) ;
687690 Some ( otherwise)
691+ } else if !is_last_arm {
692+ // Add always true guard in case of more than one arm
693+ // it creates false edges and allow MIR borrowck detects errors
694+ // FIXME(#45184) -- permit "false edges"
695+ let source_info = self . source_info ( candidate. span ) ;
696+ let true_expr = Expr {
697+ temp_lifetime : None ,
698+ ty : self . hir . tcx ( ) . types . bool ,
699+ span : DUMMY_SP ,
700+ kind : ExprKind :: Literal { literal : self . hir . true_literal ( ) } ,
701+ } ;
702+ let cond = unpack ! ( block = self . as_local_operand( block, true_expr) ) ;
703+ let otherwise = self . cfg . start_new_block ( ) ;
704+ self . cfg . terminate ( block, source_info,
705+ TerminatorKind :: if_ ( self . hir . tcx ( ) , cond, arm_block, otherwise) ) ;
706+ Some ( otherwise)
688707 } else {
689708 let source_info = self . source_info ( candidate. span ) ;
690709 self . cfg . terminate ( block, source_info,
691- TerminatorKind :: Goto { target : arm_block } ) ;
710+ TerminatorKind :: Goto { target : arm_block } ) ;
692711 None
693712 }
694713 }
0 commit comments