@@ -1015,22 +1015,30 @@ impl TerminatorKind<'_> {
10151015
10161016#[ derive( Debug , Clone , TyEncodable , TyDecodable , Hash , HashStable , PartialEq ) ]
10171017pub 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.
10201020 pub ( super ) values : SmallVec < [ Pu128 ; 1 ] > ,
10211021
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 .
10251025 //
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 :
10281028 //
1029- // branches: Vec<(ConstInt , BasicBlock)>,
1030- // otherwise: Option< BasicBlock> // exhaustive if None
1029+ // normal: SmallVec<[(Pu128 , BasicBlock); 1] >,
1030+ // otherwise: BasicBlock,
10311031 //
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.
10341042 pub ( super ) targets : SmallVec < [ BasicBlock ; 2 ] > ,
10351043}
10361044
0 commit comments