@@ -803,9 +803,28 @@ pub enum TerminatorKind<'tcx> {
803
803
/// Indicates the end of the dropping of a generator
804
804
GeneratorDrop ,
805
805
806
+ /// A block where control flow only ever takes one real path, but borrowck
807
+ /// needs to be more conservative.
806
808
FalseEdges {
809
+ /// The target normal control flow will take
807
810
real_target : BasicBlock ,
808
- imaginary_targets : Vec < BasicBlock >
811
+ /// The list of blocks control flow could conceptually take, but won't
812
+ /// in practice
813
+ imaginary_targets : Vec < BasicBlock > ,
814
+ } ,
815
+ /// A terminator for blocks that only take one path in reality, but where we
816
+ /// reserve the right to unwind in borrowck, even if it won't happen in practice.
817
+ /// This can arise in infinite loops with no function calls for example.
818
+ FalseUnwind {
819
+ /// The target normal control flow will take
820
+ real_target : BasicBlock ,
821
+ /// The imaginary cleanup block link. This particular path will never be taken
822
+ /// in practice, but in order to avoid fragility we want to always
823
+ /// consider it in borrowck. We don't want to accept programs which
824
+ /// pass borrowck only when panic=abort or some assertions are disabled
825
+ /// due to release vs. debug mode builds. This needs to be an Option because
826
+ /// of the remove_noop_landing_pads and no_landing_pads passes
827
+ unwind : Option < BasicBlock > ,
809
828
} ,
810
829
}
811
830
@@ -865,6 +884,8 @@ impl<'tcx> TerminatorKind<'tcx> {
865
884
s. extend_from_slice ( imaginary_targets) ;
866
885
s. into_cow ( )
867
886
}
887
+ FalseUnwind { real_target : t, unwind : Some ( u) } => vec ! [ t, u] . into_cow ( ) ,
888
+ FalseUnwind { real_target : ref t, unwind : None } => slice:: from_ref ( t) . into_cow ( ) ,
868
889
}
869
890
}
870
891
@@ -897,6 +918,8 @@ impl<'tcx> TerminatorKind<'tcx> {
897
918
s. extend ( imaginary_targets. iter_mut ( ) ) ;
898
919
s
899
920
}
921
+ FalseUnwind { real_target : ref mut t, unwind : Some ( ref mut u) } => vec ! [ t, u] ,
922
+ FalseUnwind { ref mut real_target, unwind : None } => vec ! [ real_target] ,
900
923
}
901
924
}
902
925
@@ -916,7 +939,8 @@ impl<'tcx> TerminatorKind<'tcx> {
916
939
TerminatorKind :: Call { cleanup : ref mut unwind, .. } |
917
940
TerminatorKind :: Assert { cleanup : ref mut unwind, .. } |
918
941
TerminatorKind :: DropAndReplace { ref mut unwind, .. } |
919
- TerminatorKind :: Drop { ref mut unwind, .. } => {
942
+ TerminatorKind :: Drop { ref mut unwind, .. } |
943
+ TerminatorKind :: FalseUnwind { ref mut unwind, .. } => {
920
944
Some ( unwind)
921
945
}
922
946
}
@@ -1045,7 +1069,8 @@ impl<'tcx> TerminatorKind<'tcx> {
1045
1069
1046
1070
write ! ( fmt, ")" )
1047
1071
} ,
1048
- FalseEdges { .. } => write ! ( fmt, "falseEdges" )
1072
+ FalseEdges { .. } => write ! ( fmt, "falseEdges" ) ,
1073
+ FalseUnwind { .. } => write ! ( fmt, "falseUnwind" ) ,
1049
1074
}
1050
1075
}
1051
1076
@@ -1087,6 +1112,8 @@ impl<'tcx> TerminatorKind<'tcx> {
1087
1112
l. resize ( imaginary_targets. len ( ) + 1 , "imaginary" . into ( ) ) ;
1088
1113
l
1089
1114
}
1115
+ FalseUnwind { unwind : Some ( _) , .. } => vec ! [ "real" . into( ) , "cleanup" . into( ) ] ,
1116
+ FalseUnwind { unwind : None , .. } => vec ! [ "real" . into( ) ] ,
1090
1117
}
1091
1118
}
1092
1119
}
@@ -2189,7 +2216,8 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> {
2189
2216
Return => Return ,
2190
2217
Unreachable => Unreachable ,
2191
2218
FalseEdges { real_target, ref imaginary_targets } =>
2192
- FalseEdges { real_target, imaginary_targets : imaginary_targets. clone ( ) }
2219
+ FalseEdges { real_target, imaginary_targets : imaginary_targets. clone ( ) } ,
2220
+ FalseUnwind { real_target, unwind } => FalseUnwind { real_target, unwind } ,
2193
2221
} ;
2194
2222
Terminator {
2195
2223
source_info : self . source_info ,
@@ -2231,7 +2259,8 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> {
2231
2259
Return |
2232
2260
GeneratorDrop |
2233
2261
Unreachable |
2234
- FalseEdges { .. } => false
2262
+ FalseEdges { .. } |
2263
+ FalseUnwind { .. } => false
2235
2264
}
2236
2265
}
2237
2266
}
0 commit comments