@@ -1015,22 +1015,30 @@ impl TerminatorKind<'_> {
1015
1015
1016
1016
#[ derive( Debug , Clone , TyEncodable , TyDecodable , Hash , HashStable , PartialEq ) ]
1017
1017
pub struct SwitchTargets {
1018
- /// Possible values. The locations to branch to in each case
1019
- /// are found in the corresponding indices from the `targets` vector.
1018
+ /// Possible values. For each value, the location to branch to is found in
1019
+ /// the corresponding element in the `targets` vector.
1020
1020
pub ( super ) values : SmallVec < [ Pu128 ; 1 ] > ,
1021
1021
1022
- /// Possible branch sites . The last element of this vector is used
1023
- /// for the otherwise branch, so targets.len() == values.len() + 1
1024
- /// should hold .
1022
+ /// Possible branch targets . The last element of this vector is used for
1023
+ /// the " otherwise" branch, so ` targets.len() == values.len() + 1` always
1024
+ /// holds .
1025
1025
//
1026
- // This invariant is quite non-obvious and also could be improved.
1027
- // One way to make this invariant is to have something like this instead :
1026
+ // Note: This invariant is non-obvious and easy to violate. This would be a
1027
+ // more rigorous representation :
1028
1028
//
1029
- // branches: Vec<(ConstInt , BasicBlock)>,
1030
- // otherwise: Option< BasicBlock> // exhaustive if None
1029
+ // normal: SmallVec<[(Pu128 , BasicBlock); 1] >,
1030
+ // otherwise: BasicBlock,
1031
1031
//
1032
- // However we’ve decided to keep this as-is until we figure a case
1033
- // where some other approach seems to be strictly better than other.
1032
+ // But it's important to have the targets in a sliceable type, because
1033
+ // target slices show up elsewhere. E.g. `TerminatorKind::InlineAsm` has a
1034
+ // boxed slice, and `TerminatorKind::FalseEdge` has a single target that
1035
+ // can be converted to a slice with `slice::from_ref`.
1036
+ //
1037
+ // Why does this matter? In functions like `TerminatorKind::successors` we
1038
+ // return `impl Iterator` and a non-slice-of-targets representation here
1039
+ // causes problems because multiple different concrete iterator types would
1040
+ // be involved and we would need a boxed trait object, which requires an
1041
+ // allocation, which is expensive if done frequently.
1034
1042
pub ( super ) targets : SmallVec < [ BasicBlock ; 2 ] > ,
1035
1043
}
1036
1044
0 commit comments