Skip to content

Commit fc9a365

Browse files
committed
Update and clarify the comment on SwitchTargets.
1 parent e90dfc9 commit fc9a365

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
@@ -1023,22 +1023,30 @@ pub enum SwitchTargetValue {
10231023

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

Comments
 (0)