@@ -816,9 +816,28 @@ pub enum TerminatorKind<'tcx> {
816
816
/// Indicates the end of the dropping of a generator
817
817
GeneratorDrop ,
818
818
819
+ /// A block where control flow only ever takes one real path, but borrowck
820
+ /// needs to be more conservative.
819
821
FalseEdges {
822
+ /// The target normal control flow will take
820
823
real_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 > ,
822
841
} ,
823
842
}
824
843
@@ -878,6 +897,8 @@ impl<'tcx> TerminatorKind<'tcx> {
878
897
s. extend_from_slice ( imaginary_targets) ;
879
898
s. into_cow ( )
880
899
}
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 ( ) ,
881
902
}
882
903
}
883
904
@@ -910,6 +931,8 @@ impl<'tcx> TerminatorKind<'tcx> {
910
931
s. extend ( imaginary_targets. iter_mut ( ) ) ;
911
932
s
912
933
}
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] ,
913
936
}
914
937
}
915
938
@@ -929,7 +952,8 @@ impl<'tcx> TerminatorKind<'tcx> {
929
952
TerminatorKind :: Call { cleanup : ref mut unwind, .. } |
930
953
TerminatorKind :: Assert { cleanup : ref mut unwind, .. } |
931
954
TerminatorKind :: DropAndReplace { ref mut unwind, .. } |
932
- TerminatorKind :: Drop { ref mut unwind, .. } => {
955
+ TerminatorKind :: Drop { ref mut unwind, .. } |
956
+ TerminatorKind :: FalseUnwind { ref mut unwind, .. } => {
933
957
Some ( unwind)
934
958
}
935
959
}
@@ -1058,7 +1082,8 @@ impl<'tcx> TerminatorKind<'tcx> {
1058
1082
1059
1083
write ! ( fmt, ")" )
1060
1084
} ,
1061
- FalseEdges { .. } => write ! ( fmt, "falseEdges" )
1085
+ FalseEdges { .. } => write ! ( fmt, "falseEdges" ) ,
1086
+ FalseUnwind { .. } => write ! ( fmt, "falseUnwind" ) ,
1062
1087
}
1063
1088
}
1064
1089
@@ -1100,6 +1125,8 @@ impl<'tcx> TerminatorKind<'tcx> {
1100
1125
l. resize ( imaginary_targets. len ( ) + 1 , "imaginary" . into ( ) ) ;
1101
1126
l
1102
1127
}
1128
+ FalseUnwind { unwind : Some ( _) , .. } => vec ! [ "real" . into( ) , "cleanup" . into( ) ] ,
1129
+ FalseUnwind { unwind : None , .. } => vec ! [ "real" . into( ) ] ,
1103
1130
}
1104
1131
}
1105
1132
}
@@ -2202,7 +2229,8 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> {
2202
2229
Return => Return ,
2203
2230
Unreachable => Unreachable ,
2204
2231
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 } ,
2206
2234
} ;
2207
2235
Terminator {
2208
2236
source_info : self . source_info ,
@@ -2244,7 +2272,8 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> {
2244
2272
Return |
2245
2273
GeneratorDrop |
2246
2274
Unreachable |
2247
- FalseEdges { .. } => false
2275
+ FalseEdges { .. } |
2276
+ FalseUnwind { .. } => false
2248
2277
}
2249
2278
}
2250
2279
}
0 commit comments