Skip to content

Commit db1ca60

Browse files
committed
Update and clarify the comment on SwitchTargets.
1 parent 8403d39 commit db1ca60

File tree

1 file changed

+19
-11
lines changed

1 file changed

+19
-11
lines changed

compiler/rustc_middle/src/mir/syntax.rs

+19-11
Original file line numberDiff line numberDiff line change
@@ -1015,22 +1015,30 @@ impl TerminatorKind<'_> {
10151015

10161016
#[derive(Debug, Clone, TyEncodable, TyDecodable, Hash, HashStable, PartialEq)]
10171017
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.
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

Comments
 (0)