@@ -816,9 +816,28 @@ pub enum TerminatorKind<'tcx> {
816816    /// Indicates the end of the dropping of a generator 
817817GeneratorDrop , 
818818
819+     /// A block where control flow only ever takes one real path, but borrowck 
820+ /// needs to be more conservative. 
819821FalseEdges  { 
822+         /// The target normal control flow will take 
820823real_target :  BasicBlock , 
821-         imaginary_targets :  Vec < BasicBlock > 
824+         /// The list of blocks control flow could conceptually take, but won't 
825+ /// in practice 
826+ imaginary_targets :  Vec < BasicBlock > , 
827+     } , 
828+     /// A terminator for blocks that only take one path in reality, but where we 
829+ /// reserve the right to unwind in borrowck, even if it won't happen in practice. 
830+ /// This can arise in infinite loops with no function calls for example. 
831+ FalseUnwind  { 
832+         /// The target normal control flow will take 
833+ real_target :  BasicBlock , 
834+         /// The imaginary cleanup block link. This particular path will never be taken 
835+ /// in practice, but in order to avoid fragility we want to always 
836+ /// consider it in borrowck. We don't want to accept programs which 
837+ /// pass borrowck only when panic=abort or some assertions are disabled 
838+ /// due to release vs. debug mode builds. This needs to be an Option because 
839+ /// of the remove_noop_landing_pads and no_landing_pads passes 
840+ unwind :  Option < BasicBlock > , 
822841    } , 
823842} 
824843
@@ -878,6 +897,8 @@ impl<'tcx> TerminatorKind<'tcx> {
878897                s. extend_from_slice ( imaginary_targets) ; 
879898                s. into_cow ( ) 
880899            } 
900+             FalseUnwind  {  real_target :  t,  unwind :  Some ( u)  }  => vec ! [ t,  u] . into_cow ( ) , 
901+             FalseUnwind  {  real_target :  ref  t,  unwind :  None  }  => slice:: from_ref ( t) . into_cow ( ) , 
881902        } 
882903    } 
883904
@@ -910,6 +931,8 @@ impl<'tcx> TerminatorKind<'tcx> {
910931                s. extend ( imaginary_targets. iter_mut ( ) ) ; 
911932                s
912933            } 
934+             FalseUnwind  {  real_target :  ref  mut  t,  unwind :  Some ( ref  mut  u)  }  => vec ! [ t,  u] , 
935+             FalseUnwind  {  ref  mut  real_target,  unwind :  None  }  => vec ! [ real_target] , 
913936        } 
914937    } 
915938
@@ -929,7 +952,8 @@ impl<'tcx> TerminatorKind<'tcx> {
929952            TerminatorKind :: Call  {  cleanup :  ref  mut  unwind,  .. }  |
930953            TerminatorKind :: Assert  {  cleanup :  ref  mut  unwind,  .. }  |
931954            TerminatorKind :: DropAndReplace  {  ref  mut  unwind,  .. }  |
932-             TerminatorKind :: Drop  {  ref  mut  unwind,  .. }  => { 
955+             TerminatorKind :: Drop  {  ref  mut  unwind,  .. }  |
956+             TerminatorKind :: FalseUnwind  {  ref  mut  unwind,  .. }  => { 
933957                Some ( unwind) 
934958            } 
935959        } 
@@ -1058,7 +1082,8 @@ impl<'tcx> TerminatorKind<'tcx> {
10581082
10591083                write ! ( fmt,  ")" ) 
10601084            } , 
1061-             FalseEdges  {  .. }  => write ! ( fmt,  "falseEdges" ) 
1085+             FalseEdges  {  .. }  => write ! ( fmt,  "falseEdges" ) , 
1086+             FalseUnwind  {  .. }  => write ! ( fmt,  "falseUnwind" ) , 
10621087        } 
10631088    } 
10641089
@@ -1100,6 +1125,8 @@ impl<'tcx> TerminatorKind<'tcx> {
11001125                l. resize ( imaginary_targets. len ( )  + 1 ,  "imaginary" . into ( ) ) ; 
11011126                l
11021127            } 
1128+             FalseUnwind  {  unwind :  Some ( _) ,  .. }  => vec ! [ "real" . into( ) ,  "cleanup" . into( ) ] , 
1129+             FalseUnwind  {  unwind :  None ,  .. }  => vec ! [ "real" . into( ) ] , 
11031130        } 
11041131    } 
11051132} 
@@ -2202,7 +2229,8 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> {
22022229            Return  => Return , 
22032230            Unreachable  => Unreachable , 
22042231            FalseEdges  {  real_target,  ref  imaginary_targets }  =>
2205-                 FalseEdges  {  real_target,  imaginary_targets :  imaginary_targets. clone ( )  } 
2232+                 FalseEdges  {  real_target,  imaginary_targets :  imaginary_targets. clone ( )  } , 
2233+             FalseUnwind  {  real_target,  unwind }  => FalseUnwind  {  real_target,  unwind } , 
22062234        } ; 
22072235        Terminator  { 
22082236            source_info :  self . source_info , 
@@ -2244,7 +2272,8 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> {
22442272            Return  |
22452273            GeneratorDrop  |
22462274            Unreachable  |
2247-             FalseEdges  {  .. }  => false 
2275+             FalseEdges  {  .. }  |
2276+             FalseUnwind  {  .. }  => false 
22482277        } 
22492278    } 
22502279} 
0 commit comments