@@ -1023,22 +1023,30 @@ pub enum SwitchTargetValue {
10231023
10241024#[ derive( Debug , Clone , TyEncodable , TyDecodable , Hash , HashStable , PartialEq ) ]
10251025pub 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.
10281028 pub ( super ) values : SmallVec < [ Pu128 ; 1 ] > ,
10291029
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 .
10331033 //
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 :
10361036 //
1037- // branches: Vec<(ConstInt , BasicBlock)>,
1038- // otherwise: Option< BasicBlock> // exhaustive if None
1037+ // normal: SmallVec<[(Pu128 , BasicBlock); 1] >,
1038+ // otherwise: BasicBlock,
10391039 //
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.
10421050 pub ( super ) targets : SmallVec < [ BasicBlock ; 2 ] > ,
10431051}
10441052
0 commit comments