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