about summary refs log tree commit diff
path: root/compiler/rustc_data_structures
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_data_structures')
-rw-r--r--compiler/rustc_data_structures/Cargo.toml6
-rw-r--r--compiler/rustc_data_structures/src/graph/dominators/tests.rs65
-rw-r--r--compiler/rustc_data_structures/src/graph/implementation/tests.rs11
-rw-r--r--compiler/rustc_data_structures/src/graph/mod.rs16
-rw-r--r--compiler/rustc_data_structures/src/graph/scc/mod.rs4
-rw-r--r--compiler/rustc_data_structures/src/graph/scc/tests.rs83
-rw-r--r--compiler/rustc_data_structures/src/lib.rs1
-rw-r--r--compiler/rustc_data_structures/src/memmap.rs16
-rw-r--r--compiler/rustc_data_structures/src/obligation_forest/tests.rs8
-rw-r--r--compiler/rustc_data_structures/src/owned_slice.rs8
-rw-r--r--compiler/rustc_data_structures/src/stack.rs12
-rw-r--r--compiler/rustc_data_structures/src/sync.rs3
-rw-r--r--compiler/rustc_data_structures/src/thousands/mod.rs16
-rw-r--r--compiler/rustc_data_structures/src/thousands/tests.rs14
-rw-r--r--compiler/rustc_data_structures/src/vec_cache.rs13
-rw-r--r--compiler/rustc_data_structures/src/vec_cache/tests.rs13
16 files changed, 178 insertions, 111 deletions
diff --git a/compiler/rustc_data_structures/Cargo.toml b/compiler/rustc_data_structures/Cargo.toml
index 889a8299c18..a8f83ca13e2 100644
--- a/compiler/rustc_data_structures/Cargo.toml
+++ b/compiler/rustc_data_structures/Cargo.toml
@@ -8,13 +8,13 @@ edition = "2021"
 arrayvec = { version = "0.7", default-features = false }
 bitflags = "2.4.1"
 either = "1.0"
-elsa = "=1.7.1"
+elsa = "1.11.0"
 ena = "0.14.3"
-indexmap = { version = "2.4.0", features = ["rustc-rayon"] }
+indexmap = "2.4.0"
 jobserver_crate = { version = "0.1.28", package = "jobserver" }
 measureme = "11"
 rustc-hash = "2.0.0"
-rustc-rayon = "0.5.0"
+rustc-rayon = { version = "0.5.1", features = ["indexmap"] }
 rustc-stable-hash = { version = "0.1.0", features = ["nightly"] }
 rustc_arena = { path = "../rustc_arena" }
 rustc_graphviz = { path = "../rustc_graphviz" }
diff --git a/compiler/rustc_data_structures/src/graph/dominators/tests.rs b/compiler/rustc_data_structures/src/graph/dominators/tests.rs
index ef82193a4b9..6c078ca7c6e 100644
--- a/compiler/rustc_data_structures/src/graph/dominators/tests.rs
+++ b/compiler/rustc_data_structures/src/graph/dominators/tests.rs
@@ -15,17 +15,10 @@ fn diamond() {
 #[test]
 fn paper() {
     // example from the paper:
-    let graph = TestGraph::new(6, &[
-        (6, 5),
-        (6, 4),
-        (5, 1),
-        (4, 2),
-        (4, 3),
-        (1, 2),
-        (2, 3),
-        (3, 2),
-        (2, 1),
-    ]);
+    let graph = TestGraph::new(
+        6,
+        &[(6, 5), (6, 4), (5, 1), (4, 2), (4, 3), (1, 2), (2, 3), (3, 2), (2, 1)],
+    );
 
     let d = dominators(&graph);
     assert_eq!(d.immediate_dominator(0), None); // <-- note that 0 is not in graph
@@ -40,19 +33,10 @@ fn paper() {
 #[test]
 fn paper_slt() {
     // example from the paper:
-    let graph = TestGraph::new(1, &[
-        (1, 2),
-        (1, 3),
-        (2, 3),
-        (2, 7),
-        (3, 4),
-        (3, 6),
-        (4, 5),
-        (5, 4),
-        (6, 7),
-        (7, 8),
-        (8, 5),
-    ]);
+    let graph = TestGraph::new(
+        1,
+        &[(1, 2), (1, 3), (2, 3), (2, 7), (3, 4), (3, 6), (4, 5), (5, 4), (6, 7), (7, 8), (8, 5)],
+    );
 
     dominators(&graph);
 }
@@ -69,21 +53,24 @@ fn immediate_dominator() {
 
 #[test]
 fn transitive_dominator() {
-    let graph = TestGraph::new(0, &[
-        // First tree branch.
-        (0, 1),
-        (1, 2),
-        (2, 3),
-        (3, 4),
-        // Second tree branch.
-        (1, 5),
-        (5, 6),
-        // Third tree branch.
-        (0, 7),
-        // These links make 0 the dominator for 2 and 3.
-        (7, 2),
-        (5, 3),
-    ]);
+    let graph = TestGraph::new(
+        0,
+        &[
+            // First tree branch.
+            (0, 1),
+            (1, 2),
+            (2, 3),
+            (3, 4),
+            // Second tree branch.
+            (1, 5),
+            (5, 6),
+            // Third tree branch.
+            (0, 7),
+            // These links make 0 the dominator for 2 and 3.
+            (7, 2),
+            (5, 3),
+        ],
+    );
 
     let d = dominators(&graph);
     assert_eq!(d.immediate_dominator(2), Some(0));
diff --git a/compiler/rustc_data_structures/src/graph/implementation/tests.rs b/compiler/rustc_data_structures/src/graph/implementation/tests.rs
index 7a240f4e58b..32a6d9ec881 100644
--- a/compiler/rustc_data_structures/src/graph/implementation/tests.rs
+++ b/compiler/rustc_data_structures/src/graph/implementation/tests.rs
@@ -110,10 +110,13 @@ fn each_adjacent_from_a() {
 #[test]
 fn each_adjacent_from_b() {
     let graph = create_graph();
-    test_adjacent_edges(&graph, NodeIndex(1), "B", &[("FB", "F"), ("AB", "A")], &[
-        ("BD", "D"),
-        ("BC", "C"),
-    ]);
+    test_adjacent_edges(
+        &graph,
+        NodeIndex(1),
+        "B",
+        &[("FB", "F"), ("AB", "A")],
+        &[("BD", "D"), ("BC", "C")],
+    );
 }
 
 #[test]
diff --git a/compiler/rustc_data_structures/src/graph/mod.rs b/compiler/rustc_data_structures/src/graph/mod.rs
index 92035e8bc48..4a1e5db6768 100644
--- a/compiler/rustc_data_structures/src/graph/mod.rs
+++ b/compiler/rustc_data_structures/src/graph/mod.rs
@@ -14,7 +14,23 @@ mod tests;
 pub trait DirectedGraph {
     type Node: Idx;
 
+    /// Returns the total number of nodes in this graph.
+    ///
+    /// Several graph algorithm implementations assume that every node ID is
+    /// strictly less than the number of nodes, i.e. nodes are densely numbered.
+    /// That assumption allows them to use `num_nodes` to allocate per-node
+    /// data structures, indexed by node.
     fn num_nodes(&self) -> usize;
+
+    /// Iterates over all nodes of a graph in ascending numeric order.
+    ///
+    /// Assumes that nodes are densely numbered, i.e. every index in
+    /// `0..num_nodes` is a valid node.
+    fn iter_nodes(
+        &self,
+    ) -> impl Iterator<Item = Self::Node> + DoubleEndedIterator + ExactSizeIterator {
+        (0..self.num_nodes()).map(<Self::Node as Idx>::new)
+    }
 }
 
 pub trait NumEdges: DirectedGraph {
diff --git a/compiler/rustc_data_structures/src/graph/scc/mod.rs b/compiler/rustc_data_structures/src/graph/scc/mod.rs
index 06fedef00fc..93f6192b10b 100644
--- a/compiler/rustc_data_structures/src/graph/scc/mod.rs
+++ b/compiler/rustc_data_structures/src/graph/scc/mod.rs
@@ -333,8 +333,8 @@ where
             to_annotation,
         };
 
-        let scc_indices = (0..num_nodes)
-            .map(G::Node::new)
+        let scc_indices = graph
+            .iter_nodes()
             .map(|node| match this.start_walk_from(node) {
                 WalkReturn::Complete { scc_index, .. } => scc_index,
                 WalkReturn::Cycle { min_depth, .. } => {
diff --git a/compiler/rustc_data_structures/src/graph/scc/tests.rs b/compiler/rustc_data_structures/src/graph/scc/tests.rs
index 7c876c82af2..373f87bfdbc 100644
--- a/compiler/rustc_data_structures/src/graph/scc/tests.rs
+++ b/compiler/rustc_data_structures/src/graph/scc/tests.rs
@@ -326,46 +326,49 @@ fn test_bug_max_leak_minimised() {
 
 #[test]
 fn test_bug_max_leak() {
-    let graph = TestGraph::new(8, &[
-        (0, 0),
-        (0, 18),
-        (0, 19),
-        (0, 1),
-        (0, 2),
-        (0, 7),
-        (0, 8),
-        (0, 23),
-        (18, 0),
-        (18, 12),
-        (19, 0),
-        (19, 25),
-        (12, 18),
-        (12, 3),
-        (12, 5),
-        (3, 12),
-        (3, 21),
-        (3, 22),
-        (5, 13),
-        (21, 3),
-        (22, 3),
-        (13, 5),
-        (13, 4),
-        (4, 13),
-        (4, 0),
-        (2, 11),
-        (7, 6),
-        (6, 20),
-        (20, 6),
-        (8, 17),
-        (17, 9),
-        (9, 16),
-        (16, 26),
-        (26, 15),
-        (15, 10),
-        (10, 14),
-        (14, 27),
-        (23, 24),
-    ]);
+    let graph = TestGraph::new(
+        8,
+        &[
+            (0, 0),
+            (0, 18),
+            (0, 19),
+            (0, 1),
+            (0, 2),
+            (0, 7),
+            (0, 8),
+            (0, 23),
+            (18, 0),
+            (18, 12),
+            (19, 0),
+            (19, 25),
+            (12, 18),
+            (12, 3),
+            (12, 5),
+            (3, 12),
+            (3, 21),
+            (3, 22),
+            (5, 13),
+            (21, 3),
+            (22, 3),
+            (13, 5),
+            (13, 4),
+            (4, 13),
+            (4, 0),
+            (2, 11),
+            (7, 6),
+            (6, 20),
+            (20, 6),
+            (8, 17),
+            (17, 9),
+            (9, 16),
+            (16, 26),
+            (26, 15),
+            (15, 10),
+            (10, 14),
+            (14, 27),
+            (23, 24),
+        ],
+    );
     let sccs: MaxReachedSccs = Sccs::new_with_annotation(&graph, |w| match w {
         22 => MaxReached(1),
         24 => MaxReached(2),
diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs
index 65d586124b3..6ef73debadd 100644
--- a/compiler/rustc_data_structures/src/lib.rs
+++ b/compiler/rustc_data_structures/src/lib.rs
@@ -76,6 +76,7 @@ pub mod sync;
 pub mod tagged_ptr;
 pub mod temp_dir;
 pub mod thinvec;
+pub mod thousands;
 pub mod transitive_relation;
 pub mod unhash;
 pub mod unord;
diff --git a/compiler/rustc_data_structures/src/memmap.rs b/compiler/rustc_data_structures/src/memmap.rs
index c7f66b2fee8..d64a5862f4e 100644
--- a/compiler/rustc_data_structures/src/memmap.rs
+++ b/compiler/rustc_data_structures/src/memmap.rs
@@ -3,13 +3,13 @@ use std::io;
 use std::ops::{Deref, DerefMut};
 
 /// A trivial wrapper for [`memmap2::Mmap`] (or `Vec<u8>` on WASM).
-#[cfg(not(target_arch = "wasm32"))]
+#[cfg(not(any(miri, target_arch = "wasm32")))]
 pub struct Mmap(memmap2::Mmap);
 
-#[cfg(target_arch = "wasm32")]
+#[cfg(any(miri, target_arch = "wasm32"))]
 pub struct Mmap(Vec<u8>);
 
-#[cfg(not(target_arch = "wasm32"))]
+#[cfg(not(any(miri, target_arch = "wasm32")))]
 impl Mmap {
     /// # Safety
     ///
@@ -29,7 +29,7 @@ impl Mmap {
     }
 }
 
-#[cfg(target_arch = "wasm32")]
+#[cfg(any(miri, target_arch = "wasm32"))]
 impl Mmap {
     #[inline]
     pub unsafe fn map(mut file: File) -> io::Result<Self> {
@@ -56,13 +56,13 @@ impl AsRef<[u8]> for Mmap {
     }
 }
 
-#[cfg(not(target_arch = "wasm32"))]
+#[cfg(not(any(miri, target_arch = "wasm32")))]
 pub struct MmapMut(memmap2::MmapMut);
 
-#[cfg(target_arch = "wasm32")]
+#[cfg(any(miri, target_arch = "wasm32"))]
 pub struct MmapMut(Vec<u8>);
 
-#[cfg(not(target_arch = "wasm32"))]
+#[cfg(not(any(miri, target_arch = "wasm32")))]
 impl MmapMut {
     #[inline]
     pub fn map_anon(len: usize) -> io::Result<Self> {
@@ -82,7 +82,7 @@ impl MmapMut {
     }
 }
 
-#[cfg(target_arch = "wasm32")]
+#[cfg(any(miri, target_arch = "wasm32"))]
 impl MmapMut {
     #[inline]
     pub fn map_anon(len: usize) -> io::Result<Self> {
diff --git a/compiler/rustc_data_structures/src/obligation_forest/tests.rs b/compiler/rustc_data_structures/src/obligation_forest/tests.rs
index 739ef74e3f7..1916a8e2b6b 100644
--- a/compiler/rustc_data_structures/src/obligation_forest/tests.rs
+++ b/compiler/rustc_data_structures/src/obligation_forest/tests.rs
@@ -349,10 +349,10 @@ fn diamond() {
     ));
     assert_eq!(d_count, 1);
     assert_eq!(ok.len(), 0);
-    assert_eq!(err, vec![super::Error {
-        error: "operation failed",
-        backtrace: vec!["D'", "A'.1", "A'"]
-    }]);
+    assert_eq!(
+        err,
+        vec![super::Error { error: "operation failed", backtrace: vec!["D'", "A'.1", "A'"] }]
+    );
 
     let errors = forest.to_errors(());
     assert_eq!(errors.len(), 0);
diff --git a/compiler/rustc_data_structures/src/owned_slice.rs b/compiler/rustc_data_structures/src/owned_slice.rs
index c8be0ab52e9..17c48aee6fa 100644
--- a/compiler/rustc_data_structures/src/owned_slice.rs
+++ b/compiler/rustc_data_structures/src/owned_slice.rs
@@ -1,15 +1,15 @@
 use std::borrow::Borrow;
 use std::ops::Deref;
+use std::sync::Arc;
 
 // Use our fake Send/Sync traits when on not parallel compiler,
 // so that `OwnedSlice` only implements/requires Send/Sync
 // for parallel compiler builds.
 use crate::sync;
-use crate::sync::Lrc;
 
 /// An owned slice.
 ///
-/// This is similar to `Lrc<[u8]>` but allows slicing and using anything as the
+/// This is similar to `Arc<[u8]>` but allows slicing and using anything as the
 /// backing buffer.
 ///
 /// See [`slice_owned`] for `OwnedSlice` construction and examples.
@@ -34,7 +34,7 @@ pub struct OwnedSlice {
     //       \/
     //      ⊂(´・◡・⊂ )∘˚˳° (I am the phantom remnant of #97770)
     #[expect(dead_code)]
-    owner: Lrc<dyn sync::Send + sync::Sync>,
+    owner: Arc<dyn sync::Send + sync::Sync>,
 }
 
 /// Makes an [`OwnedSlice`] out of an `owner` and a `slicer` function.
@@ -86,7 +86,7 @@ where
     // N.B. the HRTB on the `slicer` is important — without it the caller could provide
     // a short lived slice, unrelated to the owner.
 
-    let owner = Lrc::new(owner);
+    let owner = Arc::new(owner);
     let bytes = slicer(&*owner)?;
 
     Ok(OwnedSlice { bytes, owner })
diff --git a/compiler/rustc_data_structures/src/stack.rs b/compiler/rustc_data_structures/src/stack.rs
index 3d6d0003483..102b3640911 100644
--- a/compiler/rustc_data_structures/src/stack.rs
+++ b/compiler/rustc_data_structures/src/stack.rs
@@ -17,6 +17,18 @@ const STACK_PER_RECURSION: usize = 16 * 1024 * 1024; // 16MB
 ///
 /// Should not be sprinkled around carelessly, as it causes a little bit of overhead.
 #[inline]
+#[cfg(not(miri))]
 pub fn ensure_sufficient_stack<R>(f: impl FnOnce() -> R) -> R {
     stacker::maybe_grow(RED_ZONE, STACK_PER_RECURSION, f)
 }
+
+/// Grows the stack on demand to prevent stack overflow. Call this in strategic locations
+/// to "break up" recursive calls. E.g. almost any call to `visit_expr` or equivalent can benefit
+/// from this.
+///
+/// Should not be sprinkled around carelessly, as it causes a little bit of overhead.
+#[cfg(miri)]
+#[inline]
+pub fn ensure_sufficient_stack<R>(f: impl FnOnce() -> R) -> R {
+    f()
+}
diff --git a/compiler/rustc_data_structures/src/sync.rs b/compiler/rustc_data_structures/src/sync.rs
index 7a9533031f4..bea87a6685d 100644
--- a/compiler/rustc_data_structures/src/sync.rs
+++ b/compiler/rustc_data_structures/src/sync.rs
@@ -18,7 +18,6 @@
 //!
 //! | Type                    | Serial version      | Parallel version                |
 //! | ----------------------- | ------------------- | ------------------------------- |
-//! | `Lrc<T>`                | `rc::Rc<T>`         | `sync::Arc<T>`                  |
 //! |` Weak<T>`               | `rc::Weak<T>`       | `sync::Weak<T>`                 |
 //! | `LRef<'a, T>` [^2]      | `&'a mut T`         | `&'a T`                         |
 //! |                         |                     |                                 |
@@ -109,7 +108,7 @@ pub use std::marker::{Send, Sync};
 #[cfg(target_has_atomic = "64")]
 pub use std::sync::atomic::AtomicU64;
 pub use std::sync::atomic::{AtomicBool, AtomicU32, AtomicUsize};
-pub use std::sync::{Arc as Lrc, OnceLock, Weak};
+pub use std::sync::{OnceLock, Weak};
 
 pub use mode::{is_dyn_thread_safe, set_dyn_thread_safe_mode};
 pub use parking_lot::{
diff --git a/compiler/rustc_data_structures/src/thousands/mod.rs b/compiler/rustc_data_structures/src/thousands/mod.rs
new file mode 100644
index 00000000000..e7ab7ec2932
--- /dev/null
+++ b/compiler/rustc_data_structures/src/thousands/mod.rs
@@ -0,0 +1,16 @@
+//! This is an extremely bare-bones alternative to the `thousands` crate on
+//! crates.io, for printing large numbers in a readable fashion.
+
+#[cfg(test)]
+mod tests;
+
+// Converts the number to a string, with underscores as the thousands separator.
+pub fn format_with_underscores(n: usize) -> String {
+    let mut s = n.to_string();
+    let mut i = s.len();
+    while i > 3 {
+        i -= 3;
+        s.insert(i, '_');
+    }
+    s
+}
diff --git a/compiler/rustc_data_structures/src/thousands/tests.rs b/compiler/rustc_data_structures/src/thousands/tests.rs
new file mode 100644
index 00000000000..906605d9a93
--- /dev/null
+++ b/compiler/rustc_data_structures/src/thousands/tests.rs
@@ -0,0 +1,14 @@
+use super::*;
+
+#[test]
+fn test_format_with_underscores() {
+    assert_eq!("0", format_with_underscores(0));
+    assert_eq!("1", format_with_underscores(1));
+    assert_eq!("99", format_with_underscores(99));
+    assert_eq!("345", format_with_underscores(345));
+    assert_eq!("1_000", format_with_underscores(1_000));
+    assert_eq!("12_001", format_with_underscores(12_001));
+    assert_eq!("999_999", format_with_underscores(999_999));
+    assert_eq!("1_000_000", format_with_underscores(1_000_000));
+    assert_eq!("12_345_678", format_with_underscores(12_345_678));
+}
diff --git a/compiler/rustc_data_structures/src/vec_cache.rs b/compiler/rustc_data_structures/src/vec_cache.rs
index eb251b587c8..2ff60ab7f36 100644
--- a/compiler/rustc_data_structures/src/vec_cache.rs
+++ b/compiler/rustc_data_structures/src/vec_cache.rs
@@ -206,6 +206,19 @@ impl SlotIndex {
     }
 }
 
+/// In-memory cache for queries whose keys are densely-numbered IDs
+/// (e.g `CrateNum`, `LocalDefId`), and can therefore be used as indices
+/// into a dense vector of cached values.
+///
+/// (As of [#124780] the underlying storage is not an actual `Vec`, but rather
+/// a series of increasingly-large buckets, for improved performance when the
+/// parallel frontend is using multiple threads.)
+///
+/// Each entry in the cache stores the query's return value (`V`), and also
+/// an associated index (`I`), which in practice is a `DepNodeIndex` used for
+/// query dependency tracking.
+///
+/// [#124780]: https://github.com/rust-lang/rust/pull/124780
 pub struct VecCache<K: Idx, V, I> {
     // Entries per bucket:
     // Bucket  0:       4096 2^12
diff --git a/compiler/rustc_data_structures/src/vec_cache/tests.rs b/compiler/rustc_data_structures/src/vec_cache/tests.rs
index a05f2741362..3b65c14162e 100644
--- a/compiler/rustc_data_structures/src/vec_cache/tests.rs
+++ b/compiler/rustc_data_structures/src/vec_cache/tests.rs
@@ -58,11 +58,14 @@ fn concurrent_stress_check() {
 
 #[test]
 fn slot_entries_table() {
-    assert_eq!(ENTRIES_BY_BUCKET, [
-        4096, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304,
-        8388608, 16777216, 33554432, 67108864, 134217728, 268435456, 536870912, 1073741824,
-        2147483648
-    ]);
+    assert_eq!(
+        ENTRIES_BY_BUCKET,
+        [
+            4096, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576, 2097152,
+            4194304, 8388608, 16777216, 33554432, 67108864, 134217728, 268435456, 536870912,
+            1073741824, 2147483648
+        ]
+    );
 }
 
 #[test]