about summary refs log tree commit diff
path: root/compiler/rustc_transmute
diff options
context:
space:
mode:
authorMatthias Krüger <476013+matthiaskrgr@users.noreply.github.com>2025-05-02 19:37:56 +0200
committerGitHub <noreply@github.com>2025-05-02 19:37:56 +0200
commit429341b44543169534f168d7ad8ef74d66feb1c3 (patch)
tree62fa989e72337b52c7621ea16cbc2d7ab089cee3 /compiler/rustc_transmute
parenta2ae171b97741ebf1f7c3e7a1ca118faa91d6662 (diff)
parentb9e0ecdd7626e76f0b72ada922e5c07eae75cdf5 (diff)
downloadrust-429341b44543169534f168d7ad8ef74d66feb1c3.tar.gz
rust-429341b44543169534f168d7ad8ef74d66feb1c3.zip
Rollup merge of #140509 - tmiasko:merge-contiguous-ranges, r=jswrenn
transmutability: merge contiguous runs with a common destination

Based on #140380.

r? `@jswrenn` `@joshlf`
Diffstat (limited to 'compiler/rustc_transmute')
-rw-r--r--compiler/rustc_transmute/src/layout/dfa.rs24
-rw-r--r--compiler/rustc_transmute/src/maybe_transmutable/tests.rs2
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);