diff options
| author | Tomasz Miąsko <tomasz.miasko@gmail.com> | 2025-04-30 13:02:30 +0200 |
|---|---|---|
| committer | Tomasz Miąsko <tomasz.miasko@gmail.com> | 2025-04-30 14:35:23 +0200 |
| commit | b9e0ecdd7626e76f0b72ada922e5c07eae75cdf5 (patch) | |
| tree | c1e488c03f12ccfec5b50e77c6fa2b25e690534e | |
| parent | 88a86794b9e5bcda28b8f89e6b6264bb7bc042c4 (diff) | |
| download | rust-b9e0ecdd7626e76f0b72ada922e5c07eae75cdf5.tar.gz rust-b9e0ecdd7626e76f0b72ada922e5c07eae75cdf5.zip | |
transmutability: merge contiguous runs with a common destination
| -rw-r--r-- | compiler/rustc_transmute/src/layout/dfa.rs | 24 | ||||
| -rw-r--r-- | compiler/rustc_transmute/src/maybe_transmutable/tests.rs | 2 |
2 files changed, 19 insertions, 7 deletions
diff --git a/compiler/rustc_transmute/src/layout/dfa.rs b/compiler/rustc_transmute/src/layout/dfa.rs index 05afa28db31..6d072c336af 100644 --- a/compiler/rustc_transmute/src/layout/dfa.rs +++ b/compiler/rustc_transmute/src/layout/dfa.rs @@ -266,7 +266,7 @@ where } #[cfg(test)] - pub(crate) fn from_edges<B: Copy + Into<Byte>>( + pub(crate) fn from_edges<B: Clone + Into<Byte>>( start: u32, accept: u32, edges: &[(u32, B, u32)], @@ -275,8 +275,8 @@ where let accept = State(accept); let mut transitions: Map<State, Vec<(Byte, State)>> = Map::default(); - for (src, edge, dst) in edges.iter().copied() { - transitions.entry(State(src)).or_default().push((edge.into(), State(dst))); + for &(src, ref edge, dst) in edges.iter() { + transitions.entry(State(src)).or_default().push((edge.clone().into(), State(dst))); } let transitions = transitions @@ -401,12 +401,24 @@ mod edge_set { mut join: impl FnMut(Option<S>, Option<S>) -> S, ) -> EdgeSet<S> where - S: Copy, + S: Copy + Eq, { + let mut runs: SmallVec<[(Byte, S); 1]> = SmallVec::new(); let xs = self.runs.iter().copied(); let ys = other.runs.iter().copied(); - // FIXME(@joshlf): Merge contiguous runs with common destination. - EdgeSet { runs: union(xs, ys).map(|(range, (x, y))| (range, join(x, y))).collect() } + for (range, (x, y)) in union(xs, ys) { + let state = join(x, y); + match runs.last_mut() { + // Merge contiguous runs with a common destination. + Some(&mut (ref mut last_range, ref mut last_state)) + if last_range.end == range.start && *last_state == state => + { + last_range.end = range.end + } + _ => runs.push((range, state)), + } + } + EdgeSet { runs } } } } diff --git a/compiler/rustc_transmute/src/maybe_transmutable/tests.rs b/compiler/rustc_transmute/src/maybe_transmutable/tests.rs index fbb4639dbd6..0227ad71ae6 100644 --- a/compiler/rustc_transmute/src/maybe_transmutable/tests.rs +++ b/compiler/rustc_transmute/src/maybe_transmutable/tests.rs @@ -314,7 +314,7 @@ mod union { let u = s.clone().union(t.clone(), new_state); let expected_u = - Dfa::from_edges(b, a, &[(b, 0, c), (b, 1, d), (d, 1, a), (d, 0, a), (c, 0, a)]); + Dfa::from_edges(b, a, &[(b, 0..=0, c), (b, 1..=1, d), (d, 0..=1, a), (c, 0..=0, a)]); assert_eq!(u, expected_u); |
