diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs index e8779d6ee6869..cc922cf8df6f0 100644 --- a/compiler/rustc_abi/src/layout.rs +++ b/compiler/rustc_abi/src/layout.rs @@ -5,8 +5,8 @@ use std::range::{RangeFrom, RangeInclusive, RangeToInclusive}; use std::{cmp, iter}; use rustc_hashes::Hash64; -use rustc_index::Idx; use rustc_index::bit_set::BitMatrix; +use rustc_index::{Idx, StableIdx}; use tracing::{debug, trace}; use crate::{ @@ -88,8 +88,8 @@ rustc_index::newtype_index! { // for non-ZST uninhabited data (mostly partial initialization). fn absent<'a, FieldIdx, VariantIdx, F>(fields: &IndexSlice) -> bool where - FieldIdx: Idx, - VariantIdx: Idx, + FieldIdx: StableIdx, + VariantIdx: StableIdx, F: Deref> + fmt::Debug, { let uninhabited = fields.iter().any(|f| f.is_uninhabited()); @@ -178,7 +178,7 @@ impl LayoutCalculator { Self { cx } } - pub fn array_like( + pub fn array_like( &self, element: &LayoutData, count_if_sized: Option, // None for slices @@ -208,8 +208,8 @@ impl LayoutCalculator { number_of_vectors: NumScalableVectors, ) -> LayoutCalculatorResult where - FieldIdx: Idx, - VariantIdx: Idx, + FieldIdx: StableIdx, + VariantIdx: StableIdx, F: AsRef> + fmt::Debug, { vector_type_layout( @@ -227,8 +227,8 @@ impl LayoutCalculator { repr_packed: bool, ) -> LayoutCalculatorResult where - FieldIdx: Idx, - VariantIdx: Idx, + FieldIdx: StableIdx, + VariantIdx: StableIdx, F: AsRef> + fmt::Debug, { let kind = if repr_packed { SimdVectorKind::PackedFixed } else { SimdVectorKind::Fixed }; @@ -242,9 +242,9 @@ impl LayoutCalculator { pub fn coroutine< 'a, F: Deref> + fmt::Debug + Copy, - VariantIdx: Idx, - FieldIdx: Idx, - LocalIdx: Idx, + VariantIdx: StableIdx, + FieldIdx: StableIdx, + LocalIdx: StableIdx, >( &self, local_layouts: &IndexSlice, @@ -265,8 +265,8 @@ impl LayoutCalculator { pub fn univariant< 'a, - FieldIdx: Idx, - VariantIdx: Idx, + FieldIdx: StableIdx, + VariantIdx: StableIdx, F: Deref> + fmt::Debug + Copy, >( &self, @@ -340,8 +340,8 @@ impl LayoutCalculator { pub fn layout_of_struct_or_enum< 'a, - FieldIdx: Idx, - VariantIdx: Idx, + FieldIdx: StableIdx, + VariantIdx: StableIdx, F: Deref> + fmt::Debug + Copy, >( &self, @@ -394,8 +394,8 @@ impl LayoutCalculator { pub fn layout_of_union< 'a, - FieldIdx: Idx, - VariantIdx: Idx, + FieldIdx: StableIdx, + VariantIdx: StableIdx, F: Deref> + fmt::Debug + Copy, >( &self, @@ -522,8 +522,8 @@ impl LayoutCalculator { /// single-variant enums are just structs, if you think about it fn layout_of_struct< 'a, - FieldIdx: Idx, - VariantIdx: Idx, + FieldIdx: StableIdx, + VariantIdx: StableIdx, F: Deref> + fmt::Debug + Copy, >( &self, @@ -575,8 +575,8 @@ impl LayoutCalculator { fn layout_of_enum< 'a, - FieldIdx: Idx, - VariantIdx: Idx, + FieldIdx: StableIdx, + VariantIdx: StableIdx, F: Deref> + fmt::Debug + Copy, >( &self, @@ -1080,8 +1080,8 @@ impl LayoutCalculator { fn univariant_biased< 'a, - FieldIdx: Idx, - VariantIdx: Idx, + FieldIdx: StableIdx, + VariantIdx: StableIdx, F: Deref> + fmt::Debug + Copy, >( &self, @@ -1426,8 +1426,8 @@ impl LayoutCalculator { fn format_field_niches< 'a, - FieldIdx: Idx, - VariantIdx: Idx, + FieldIdx: StableIdx, + VariantIdx: StableIdx, F: Deref> + fmt::Debug, >( &self, @@ -1472,8 +1472,8 @@ fn vector_type_layout( count: u64, ) -> LayoutCalculatorResult where - FieldIdx: Idx, - VariantIdx: Idx, + FieldIdx: StableIdx, + VariantIdx: StableIdx, F: AsRef> + fmt::Debug, { let elt = element.as_ref(); diff --git a/compiler/rustc_abi/src/layout/coroutine.rs b/compiler/rustc_abi/src/layout/coroutine.rs index fd68d06c93829..bd562bc9e4db1 100644 --- a/compiler/rustc_abi/src/layout/coroutine.rs +++ b/compiler/rustc_abi/src/layout/coroutine.rs @@ -22,7 +22,7 @@ use std::iter; use rustc_index::bit_set::{BitMatrix, DenseBitSet}; -use rustc_index::{Idx, IndexSlice, IndexVec}; +use rustc_index::{IndexSlice, IndexVec, StableIdx}; use tracing::{debug, trace}; use crate::{ @@ -39,7 +39,11 @@ enum SavedLocalEligibility { } /// Compute the eligibility and assignment of each local. -fn coroutine_saved_local_eligibility( +fn coroutine_saved_local_eligibility< + VariantIdx: StableIdx, + FieldIdx: StableIdx, + LocalIdx: StableIdx, +>( nb_locals: usize, variant_fields: &IndexSlice>, storage_conflicts: &BitMatrix, @@ -139,9 +143,9 @@ fn coroutine_saved_local_eligibility> + core::fmt::Debug + Copy, - VariantIdx: Idx, - FieldIdx: Idx, - LocalIdx: Idx, + VariantIdx: StableIdx, + FieldIdx: StableIdx, + LocalIdx: StableIdx, >( calc: &super::LayoutCalculator, local_layouts: &IndexSlice, diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index aa58ac4a62eca..3ac9bf4904044 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -608,7 +608,8 @@ fn index_ast<'tcx>( let index = indexer.index; let resolver = Arc::new(resolver); return tcx.arena.alloc_index_slice_from_iter::( - index.into_iter().map(|owner| Steal::new((Arc::clone(&resolver), owner))), + // Using `unstable_into_iter` is fine here, since `index` was assigned deterministically here + index.unstable_into_iter().map(|owner| Steal::new((Arc::clone(&resolver), owner))), ); struct Indexer<'s, 'hir> { diff --git a/compiler/rustc_borrowck/src/constraints/mod.rs b/compiler/rustc_borrowck/src/constraints/mod.rs index 98f418f12ef2a..b4b24d753221c 100644 --- a/compiler/rustc_borrowck/src/constraints/mod.rs +++ b/compiler/rustc_borrowck/src/constraints/mod.rs @@ -103,6 +103,7 @@ impl<'tcx> fmt::Debug for OutlivesConstraint<'tcx> { } rustc_index::newtype_index! { + #[orderable] #[debug_format = "OutlivesConstraintIndex({})"] pub(crate) struct OutlivesConstraintIndex {} } diff --git a/compiler/rustc_data_structures/src/graph/dominators/mod.rs b/compiler/rustc_data_structures/src/graph/dominators/mod.rs index b7ddd52e9ac13..6df73d8575f25 100644 --- a/compiler/rustc_data_structures/src/graph/dominators/mod.rs +++ b/compiler/rustc_data_structures/src/graph/dominators/mod.rs @@ -9,7 +9,7 @@ //! Thomas Lengauer and Robert Endre Tarjan. //! -use rustc_index::{Idx, IndexSlice, IndexVec}; +use rustc_index::{Idx, IndexSlice, IndexVec, StableIdx}; use super::ControlFlowGraph; @@ -414,7 +414,7 @@ struct Time { finish: u32, } -fn compute_access_time( +fn compute_access_time( start_node: N, immediate_dominators: &IndexSlice>, ) -> IndexVec { diff --git a/compiler/rustc_data_structures/src/graph/linked_graph/mod.rs b/compiler/rustc_data_structures/src/graph/linked_graph/mod.rs index cecb051172598..dff92145446b1 100644 --- a/compiler/rustc_data_structures/src/graph/linked_graph/mod.rs +++ b/compiler/rustc_data_structures/src/graph/linked_graph/mod.rs @@ -23,7 +23,7 @@ use std::fmt::Debug; use rustc_index::bit_set::DenseBitSet; -use rustc_index::{Idx, IndexSlice, IndexVec}; +use rustc_index::{Idx, IndexSlice, IndexVec, StableIdx}; use tracing::debug; #[cfg(test)] @@ -100,6 +100,8 @@ impl Idx for NodeIndex { } } +impl StableIdx for NodeIndex {} + impl LinkedGraph { pub fn new() -> Self { Self { nodes: IndexVec::new(), edges: Vec::new() } diff --git a/compiler/rustc_data_structures/src/graph/mod.rs b/compiler/rustc_data_structures/src/graph/mod.rs index 20416b472b210..d0b107a6c2bef 100644 --- a/compiler/rustc_data_structures/src/graph/mod.rs +++ b/compiler/rustc_data_structures/src/graph/mod.rs @@ -1,4 +1,4 @@ -use rustc_index::Idx; +use rustc_index::{Idx, StableIdx}; pub mod dominators; pub mod iterate; @@ -12,7 +12,7 @@ pub mod vec_graph; mod tests; pub trait DirectedGraph { - type Node: Idx; + type Node: StableIdx; /// Returns the total number of nodes in this graph. /// diff --git a/compiler/rustc_data_structures/src/graph/scc/mod.rs b/compiler/rustc_data_structures/src/graph/scc/mod.rs index c04688e0a49fa..feffaaf3c76c8 100644 --- a/compiler/rustc_data_structures/src/graph/scc/mod.rs +++ b/compiler/rustc_data_structures/src/graph/scc/mod.rs @@ -13,7 +13,7 @@ use std::fmt::Debug; use std::marker::PhantomData; use std::ops::Range; -use rustc_index::{Idx, IndexSlice, IndexVec}; +use rustc_index::{IndexSlice, IndexVec, StableIdx}; use tracing::{debug, instrument, trace}; use crate::fx::FxHashSet; @@ -42,18 +42,18 @@ pub trait Annotation: Debug + Copy { } /// An accumulator for annotations. -pub trait Annotations { +pub trait Annotations { type Ann: Annotation; - type SccIdx: Idx + Ord; + type SccIdx: StableIdx + Ord; fn new(&self, element: N) -> Self::Ann; fn annotate_scc(&mut self, scc: Self::SccIdx, annotation: Self::Ann); } /// The nil annotation accumulator, which does nothing. -struct NoAnnotations(PhantomData); +struct NoAnnotations(PhantomData); -impl Annotations for NoAnnotations { +impl Annotations for NoAnnotations { type SccIdx = S; type Ann = (); fn new(&self, _element: N) {} @@ -70,7 +70,7 @@ impl Annotation for () { /// the index type for the graph nodes and `S` is the index type for /// the SCCs. We can map from each node to the SCC that it /// participates in, and we also have the successors of each SCC. -pub struct Sccs { +pub struct Sccs { /// For each node, what is the SCC index of the SCC to which it /// belongs. scc_indices: IndexVec, @@ -92,7 +92,7 @@ struct SccDetails { // is difficult when it's publicly inspectable. // // Obey the law of Demeter! -struct SccData { +struct SccData { /// Maps SCC indices to their metadata, including /// offsets into `all_successors`. scc_details: IndexVec, @@ -103,7 +103,7 @@ struct SccData { all_successors: Vec, } -impl Sccs { +impl Sccs { /// Compute SCCs without annotations. pub fn new(graph: &impl Successors) -> Self { Self::new_with_annotation(graph, &mut NoAnnotations(PhantomData::)) @@ -159,7 +159,7 @@ impl Sccs { } } -impl DirectedGraph for Sccs { +impl DirectedGraph for Sccs { type Node = S; fn num_nodes(&self) -> usize { @@ -167,19 +167,19 @@ impl DirectedGraph for Sccs { } } -impl NumEdges for Sccs { +impl NumEdges for Sccs { fn num_edges(&self) -> usize { self.scc_data.all_successors.len() } } -impl Successors for Sccs { +impl Successors for Sccs { fn successors(&self, node: S) -> impl Iterator { self.successors(node).iter().cloned() } } -impl SccData { +impl SccData { /// Number of SCCs, fn len(&self) -> usize { self.scc_details.len() diff --git a/compiler/rustc_data_structures/src/graph/vec_graph/mod.rs b/compiler/rustc_data_structures/src/graph/vec_graph/mod.rs index 96784c2540aa3..cff47994629a0 100644 --- a/compiler/rustc_data_structures/src/graph/vec_graph/mod.rs +++ b/compiler/rustc_data_structures/src/graph/vec_graph/mod.rs @@ -1,4 +1,4 @@ -use rustc_index::{Idx, IndexVec}; +use rustc_index::{IndexVec, StableIdx}; use crate::graph::{DirectedGraph, NumEdges, Predecessors, Successors}; @@ -8,7 +8,7 @@ mod tests; /// A directed graph, efficient for cases where node indices are pre-existing. /// /// If `BR` is true, the graph will store back-references, allowing you to get predecessors. -pub struct VecGraph { +pub struct VecGraph { // This is basically a `HashMap, If>)>` -- a map from a node index, to // a list of targets of outgoing edges and (if enabled) a list of sources of incoming edges. // @@ -64,7 +64,7 @@ pub struct VecGraph { edge_targets: Vec, } -impl VecGraph { +impl VecGraph { pub fn new(num_nodes: usize, mut edge_pairs: Vec<(N, N)>) -> Self { let num_edges = edge_pairs.len(); @@ -129,7 +129,7 @@ impl VecGraph { } } -impl VecGraph { +impl VecGraph { /// Gets the predecessors for `target` as a slice. pub fn predecessors(&self, target: N) -> &[N] { assert!(target.index() < self.num_nodes()); @@ -149,7 +149,7 @@ impl VecGraph { /// - `associated_edge_targets` are the edge *targets* in the same order as sources /// - `edge_targets` is the vec of targets to be extended /// - `node_starts` is the index to be filled -fn create_index( +fn create_index( num_nodes: usize, sorted_edge_sources: &mut dyn Iterator, associated_edge_targets: &mut dyn Iterator, @@ -201,7 +201,7 @@ fn create_index( assert_eq!(node_starts.len(), num_nodes + 1); } -impl DirectedGraph for VecGraph { +impl DirectedGraph for VecGraph { type Node = N; fn num_nodes(&self) -> usize { @@ -213,7 +213,7 @@ impl DirectedGraph for VecGraph { } } -impl NumEdges for VecGraph { +impl NumEdges for VecGraph { fn num_edges(&self) -> usize { match BR { false => self.edge_targets.len(), @@ -223,13 +223,13 @@ impl NumEdges for VecGraph { } } -impl Successors for VecGraph { +impl Successors for VecGraph { fn successors(&self, node: N) -> impl Iterator { self.successors(node).iter().cloned() } } -impl Predecessors for VecGraph { +impl Predecessors for VecGraph { fn predecessors(&self, node: Self::Node) -> impl Iterator { self.predecessors(node).iter().cloned() } diff --git a/compiler/rustc_data_structures/src/sorted_map/index_map.rs b/compiler/rustc_data_structures/src/sorted_map/index_map.rs index f08f343085505..4df901463f5fd 100644 --- a/compiler/rustc_data_structures/src/sorted_map/index_map.rs +++ b/compiler/rustc_data_structures/src/sorted_map/index_map.rs @@ -2,7 +2,7 @@ use std::hash::{Hash, Hasher}; -use rustc_index::{Idx, IndexVec}; +use rustc_index::{Idx, IndexVec, StableIdx}; use rustc_macros::StableHash; /// An indexed multi-map that preserves insertion order while permitting both *O*(log *n*) lookup of @@ -52,26 +52,26 @@ impl SortedIndexMultiMap { /// Returns an iterator over the items in the map in insertion order. #[inline] - pub fn into_iter(self) -> impl DoubleEndedIterator { - self.items.into_iter() + pub fn unstable_into_iter(self) -> impl DoubleEndedIterator { + self.items.unstable_into_iter() } /// Returns an iterator over the items in the map in insertion order along with their indices. #[inline] - pub fn into_iter_enumerated(self) -> impl DoubleEndedIterator { - self.items.into_iter_enumerated() + pub fn unstable_into_iter_enumerated(self) -> impl DoubleEndedIterator { + self.items.unstable_into_iter_enumerated() } /// Returns an iterator over the items in the map in insertion order. #[inline] - pub fn iter(&self) -> impl '_ + DoubleEndedIterator { - self.items.iter().map(|(k, v)| (k, v)) + pub fn unstable_iter(&self) -> impl '_ + DoubleEndedIterator { + self.items.unstable_iter().map(|(k, v)| (k, v)) } /// Returns an iterator over the items in the map in insertion order along with their indices. #[inline] - pub fn iter_enumerated(&self) -> impl '_ + DoubleEndedIterator { - self.items.iter_enumerated().map(|(i, (k, v))| (i, (k, v))) + pub fn unstable_iter_enumerated(&self) -> impl '_ + DoubleEndedIterator { + self.items.unstable_iter_enumerated().map(|(i, (k, v))| (i, (k, v))) } /// Returns the item in the map with the given index. @@ -109,6 +109,32 @@ impl SortedIndexMultiMap { } } +impl SortedIndexMultiMap { + /// Returns an iterator over the items in the map in insertion order. + #[inline] + pub fn into_iter(self) -> impl DoubleEndedIterator { + self.unstable_into_iter() + } + + /// Returns an iterator over the items in the map in insertion order along with their indices. + #[inline] + pub fn into_iter_enumerated(self) -> impl DoubleEndedIterator { + self.unstable_into_iter_enumerated() + } + + /// Returns an iterator over the items in the map in insertion order. + #[inline] + pub fn iter(&self) -> impl '_ + DoubleEndedIterator { + self.unstable_iter() + } + + /// Returns an iterator over the items in the map in insertion order along with their indices. + #[inline] + pub fn iter_enumerated(&self) -> impl '_ + DoubleEndedIterator { + self.unstable_iter_enumerated() + } +} + impl Eq for SortedIndexMultiMap {} impl PartialEq for SortedIndexMultiMap { fn eq(&self, other: &Self) -> bool { @@ -133,7 +159,8 @@ impl FromIterator<(K, V)> for SortedIndexMultiMap { J: IntoIterator, { let items = IndexVec::::from_iter(iter); - let mut idx_sorted_by_item_key: Vec<_> = items.indices().collect(); + // its ok to use `unstable_indices` here, since we will be sorting it right away + let mut idx_sorted_by_item_key: Vec<_> = items.unstable_indices().collect(); // `sort_by_key` is stable, so insertion order is preserved for duplicate items. idx_sorted_by_item_key.sort_by_key(|&idx| &items[idx].0); diff --git a/compiler/rustc_data_structures/src/union_find.rs b/compiler/rustc_data_structures/src/union_find.rs index ef73cd7ab40ab..c7a842f8a7a3c 100644 --- a/compiler/rustc_data_structures/src/union_find.rs +++ b/compiler/rustc_data_structures/src/union_find.rs @@ -91,6 +91,8 @@ impl UnionFind { /// Takes a "snapshot" of the current state of this disjoint-set forest, in /// the form of a vector that directly maps each key to its current root. pub fn snapshot(&mut self) -> IndexVec { - self.table.indices().map(|key| self.find(key)).collect() + // its ok to use unstable iteration here, since anybody trying to iterate the result will + // still have to use unstable iteration if Key did not implement `StableIdx` + self.table.unstable_indices().map(|key| self.find(key)).collect() } } diff --git a/compiler/rustc_hir_id/src/definitions.rs b/compiler/rustc_hir_id/src/definitions.rs index 50f7a15b19adf..be80f82d4b0ff 100644 --- a/compiler/rustc_hir_id/src/definitions.rs +++ b/compiler/rustc_hir_id/src/definitions.rs @@ -345,11 +345,11 @@ impl Definitions { def_id } - pub fn enumerated_keys_and_path_hashes( + pub fn unstable_enumerated_keys_and_path_hashes( &self, ) -> impl Iterator + ExactSizeIterator { self.def_id_to_key - .iter_enumerated() + .unstable_iter_enumerated() .map(move |(def_id, key)| (def_id.local_def_index, key, self.def_path_hash(def_id))) } diff --git a/compiler/rustc_index/src/bit_set.rs b/compiler/rustc_index/src/bit_set.rs index b1b26bfce7b2f..c244edeb673e0 100644 --- a/compiler/rustc_index/src/bit_set.rs +++ b/compiler/rustc_index/src/bit_set.rs @@ -7,6 +7,7 @@ use Chunk::*; #[cfg(feature = "nightly")] use rustc_macros::{Decodable_NoContext, Encodable_NoContext}; +use crate::idx::StableIdx; use crate::{Idx, IndexVec}; #[cfg(test)] @@ -1575,8 +1576,8 @@ impl SparseBitMatrix { self.ensure_row(row).insert_all(); } - pub fn rows(&self) -> impl Iterator { - self.rows.indices() + pub fn unstable_rows(&self) -> impl Iterator { + self.rows.unstable_indices() } /// Iterates through all the columns set to true in a given row of @@ -1590,6 +1591,12 @@ impl SparseBitMatrix { } } +impl SparseBitMatrix { + pub fn rows(&self) -> impl Iterator { + self.unstable_rows() + } +} + #[inline] fn num_words(domain_size: T) -> usize { domain_size.index().div_ceil(WORD_BITS) diff --git a/compiler/rustc_index/src/idx.rs b/compiler/rustc_index/src/idx.rs index 60c4dd90d8f66..e6c1d45b0278b 100644 --- a/compiler/rustc_index/src/idx.rs +++ b/compiler/rustc_index/src/idx.rs @@ -23,6 +23,17 @@ pub trait Idx: Copy + 'static + Eq + PartialEq + Debug + Hash { } } +/// An index type where iteration is stable between runs. Allows usage of iterator functions for +/// `IndexVec` and `IndexSlice`. Otherwise only the `unstable_*` variants of these functions is +/// available +/// +/// Most indices should implement this, however indices into global tables, initialized from +/// multiple threads should not. A great example of such an unstable index is `LocalDefId`, which +/// can be created on the fly inside queries executed in parallel. +/// +/// For index types defined with `newtype_index!`, adding `#[orderable]` automatically derives this. +pub trait StableIdx: Idx {} + impl Idx for usize { #[inline] fn new(idx: usize) -> Self { @@ -34,6 +45,8 @@ impl Idx for usize { } } +impl StableIdx for usize {} + impl Idx for u32 { #[inline] fn new(idx: usize) -> Self { @@ -46,6 +59,8 @@ impl Idx for u32 { } } +impl StableIdx for u32 {} + /// Helper trait for indexing operations with a custom index type. pub trait IntoSliceIdx { type Output: SliceIndex; diff --git a/compiler/rustc_index/src/interval.rs b/compiler/rustc_index/src/interval.rs index b7b1531e50857..06748b5638a38 100644 --- a/compiler/rustc_index/src/interval.rs +++ b/compiler/rustc_index/src/interval.rs @@ -4,7 +4,7 @@ use std::ops::{Bound, Range, RangeBounds}; use smallvec::SmallVec; -use crate::idx::Idx; +use crate::idx::{Idx, StableIdx}; use crate::vec::IndexVec; #[cfg(test)] @@ -362,16 +362,16 @@ impl SparseIntervalMatrix { SparseIntervalMatrix { rows: IndexVec::new(), column_size } } - pub fn rows(&self) -> impl Iterator { - self.rows.indices() + pub fn unstable_rows(&self) -> impl Iterator { + self.rows.unstable_indices() } pub fn row(&self, row: R) -> Option<&IntervalSet> { self.rows.get(row) } - pub fn iter_enumerated(&self) -> impl Iterator)> { - self.rows.iter_enumerated() + pub fn unstable_iter_enumerated(&self) -> impl Iterator)> { + self.rows.unstable_iter_enumerated() } fn ensure_row(&mut self, row: R) -> &mut IntervalSet { @@ -421,3 +421,13 @@ impl SparseIntervalMatrix { self.row(row).is_some_and(|r| r.contains(point)) } } + +impl SparseIntervalMatrix { + pub fn rows(&self) -> impl Iterator { + self.unstable_rows() + } + + pub fn iter_enumerated(&self) -> impl Iterator)> { + self.unstable_iter_enumerated() + } +} diff --git a/compiler/rustc_index/src/lib.rs b/compiler/rustc_index/src/lib.rs index c84b06769e081..0545a5347d045 100644 --- a/compiler/rustc_index/src/lib.rs +++ b/compiler/rustc_index/src/lib.rs @@ -12,7 +12,7 @@ mod idx; mod slice; mod vec; -pub use idx::{Idx, IntoSliceIdx}; +pub use idx::{Idx, IntoSliceIdx, StableIdx}; pub use rustc_index_macros::newtype_index; pub use slice::IndexSlice; #[doc(no_inline)] diff --git a/compiler/rustc_index/src/slice.rs b/compiler/rustc_index/src/slice.rs index 415fe370b702c..985a9a23f694b 100644 --- a/compiler/rustc_index/src/slice.rs +++ b/compiler/rustc_index/src/slice.rs @@ -4,6 +4,7 @@ use std::ops::{Index, IndexMut, RangeBounds}; use std::slice::GetDisjointMutError::*; use std::slice::{self, SliceIndex}; +use crate::idx::StableIdx; use crate::{Idx, IndexVec, IntoSliceIdx}; /// A view into contiguous `T`s, indexed by `I` rather than by `usize`. @@ -60,19 +61,21 @@ impl IndexSlice { } #[inline] - pub fn iter(&self) -> slice::Iter<'_, T> { + pub fn unstable_iter(&self) -> slice::Iter<'_, T> { self.raw.iter() } #[inline] - pub fn iter_enumerated(&self) -> impl DoubleEndedIterator + ExactSizeIterator { + pub fn unstable_iter_enumerated( + &self, + ) -> impl DoubleEndedIterator + ExactSizeIterator { // Allow the optimizer to elide the bounds checking when creating each index. let _ = I::new(self.len()); self.raw.iter().enumerate().map(|(n, t)| (I::new(n), t)) } #[inline] - pub fn indices( + pub fn unstable_indices( &self, ) -> impl DoubleEndedIterator + ExactSizeIterator + Clone + 'static { // Allow the optimizer to elide the bounds checking when creating each index. @@ -81,12 +84,12 @@ impl IndexSlice { } #[inline] - pub fn iter_mut(&mut self) -> slice::IterMut<'_, T> { + pub fn unstable_iter_mut(&mut self) -> slice::IterMut<'_, T> { self.raw.iter_mut() } #[inline] - pub fn iter_enumerated_mut( + pub fn unstable_iter_enumerated_mut( &mut self, ) -> impl DoubleEndedIterator + ExactSizeIterator { // Allow the optimizer to elide the bounds checking when creating each index. @@ -176,6 +179,36 @@ impl IndexSlice { } } } +impl IndexSlice { + #[inline] + pub fn iter(&self) -> slice::Iter<'_, T> { + self.unstable_iter() + } + + #[inline] + pub fn iter_enumerated(&self) -> impl DoubleEndedIterator + ExactSizeIterator { + self.unstable_iter_enumerated() + } + + #[inline] + pub fn indices( + &self, + ) -> impl DoubleEndedIterator + ExactSizeIterator + Clone + 'static { + self.unstable_indices() + } + + #[inline] + pub fn iter_mut(&mut self) -> slice::IterMut<'_, T> { + self.unstable_iter_mut() + } + + #[inline] + pub fn iter_enumerated_mut( + &mut self, + ) -> impl DoubleEndedIterator + ExactSizeIterator { + self.unstable_iter_enumerated_mut() + } +} impl IndexSlice { /// Invert a bijective mapping, i.e. `invert(map)[y] = x` if `map[x] = y`, @@ -184,18 +217,18 @@ impl IndexSlice { // FIXME(eddyb) build a better abstraction for permutations, if possible. pub fn invert_bijective_mapping(&self) -> IndexVec { debug_assert_eq!( - self.iter().map(|x| x.index() as u128).sum::(), + self.unstable_iter().map(|x| x.index() as u128).sum::(), (0..self.len() as u128).sum::(), "The values aren't 0..N in input {self:?}", ); let mut inverse = IndexVec::from_elem_n(Idx::new(0), self.len()); - for (i1, &i2) in self.iter_enumerated() { + for (i1, &i2) in self.unstable_iter_enumerated() { inverse[i2] = i1; } debug_assert_eq!( - inverse.iter().map(|x| x.index() as u128).sum::(), + inverse.unstable_iter().map(|x| x.index() as u128).sum::(), (0..inverse.len() as u128).sum::(), "The values aren't 0..N in result {self:?}", ); @@ -226,7 +259,7 @@ impl> IndexMut for IndexSlice { } } -impl<'a, I: Idx, T> IntoIterator for &'a IndexSlice { +impl<'a, I: StableIdx, T> IntoIterator for &'a IndexSlice { type Item = &'a T; type IntoIter = slice::Iter<'a, T>; @@ -236,7 +269,7 @@ impl<'a, I: Idx, T> IntoIterator for &'a IndexSlice { } } -impl<'a, I: Idx, T> IntoIterator for &'a mut IndexSlice { +impl<'a, I: StableIdx, T> IntoIterator for &'a mut IndexSlice { type Item = &'a mut T; type IntoIter = slice::IterMut<'a, T>; diff --git a/compiler/rustc_index/src/vec.rs b/compiler/rustc_index/src/vec.rs index 97aad8e6e8c04..7224c3b862a08 100644 --- a/compiler/rustc_index/src/vec.rs +++ b/compiler/rustc_index/src/vec.rs @@ -7,7 +7,7 @@ use std::{fmt, slice, vec}; #[cfg(feature = "nightly")] use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; -use crate::{Idx, IndexSlice}; +use crate::{Idx, IndexSlice, StableIdx}; /// An owned contiguous collection of `T`s, indexed by `I` rather than by `usize`. /// @@ -122,12 +122,12 @@ impl IndexVec { } #[inline] - pub fn into_iter(self) -> vec::IntoIter { + pub fn unstable_into_iter(self) -> vec::IntoIter { self.raw.into_iter() } #[inline] - pub fn into_iter_enumerated( + pub fn unstable_into_iter_enumerated( self, ) -> impl DoubleEndedIterator + ExactSizeIterator { // Allow the optimizer to elide the bounds checking when creating each index. @@ -136,12 +136,12 @@ impl IndexVec { } #[inline] - pub fn drain>(&mut self, range: R) -> impl Iterator { + pub fn unstable_drain>(&mut self, range: R) -> impl Iterator { self.raw.drain(range) } #[inline] - pub fn drain_enumerated>( + pub fn unstable_drain_enumerated>( &mut self, range: R, ) -> impl Iterator { @@ -204,6 +204,33 @@ impl IndexVec { } } +impl IndexVec { + #[inline] + pub fn into_iter(self) -> vec::IntoIter { + self.unstable_into_iter() + } + + #[inline] + pub fn into_iter_enumerated( + self, + ) -> impl DoubleEndedIterator + ExactSizeIterator { + self.unstable_into_iter_enumerated() + } + + #[inline] + pub fn drain>(&mut self, range: R) -> impl Iterator { + self.unstable_drain(range) + } + + #[inline] + pub fn drain_enumerated>( + &mut self, + range: R, + ) -> impl Iterator { + self.unstable_drain_enumerated(range) + } +} + /// `IndexVec` is often used as a map, so it provides some map-like APIs. impl IndexVec> { #[inline] @@ -247,7 +274,7 @@ impl fmt::Debug for IndexVec { impl<'a, I: Idx, T: fmt::Debug> fmt::Debug for IndexSliceMapView<'a, I, T> { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { let mut entries = fmt.debug_map(); - for (idx, val) in self.0.iter_enumerated() { + for (idx, val) in self.0.unstable_iter_enumerated() { entries.entry(&idx, val); } entries.finish() @@ -257,7 +284,7 @@ impl<'a, I: Idx, T: fmt::Debug> fmt::Debug for IndexSliceMapView<'a, I, T> { impl<'a, I: Idx, T: fmt::Debug> fmt::Debug for IndexSliceMapViewCompact<'a, I, T> { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { let mut entries = fmt.debug_map(); - for (idx, val) in self.0.iter_enumerated() { + for (idx, val) in self.0.unstable_iter_enumerated() { if let Some(val) = val { entries.entry(&idx, val); } @@ -323,7 +350,7 @@ impl FromIterator for IndexVec { } } -impl IntoIterator for IndexVec { +impl IntoIterator for IndexVec { type Item = T; type IntoIter = vec::IntoIter; @@ -333,7 +360,7 @@ impl IntoIterator for IndexVec { } } -impl<'a, I: Idx, T> IntoIterator for &'a IndexVec { +impl<'a, I: StableIdx, T> IntoIterator for &'a IndexVec { type Item = &'a T; type IntoIter = slice::Iter<'a, T>; @@ -343,7 +370,7 @@ impl<'a, I: Idx, T> IntoIterator for &'a IndexVec { } } -impl<'a, I: Idx, T> IntoIterator for &'a mut IndexVec { +impl<'a, I: StableIdx, T> IntoIterator for &'a mut IndexVec { type Item = &'a mut T; type IntoIter = slice::IterMut<'a, T>; diff --git a/compiler/rustc_index_macros/src/newtype.rs b/compiler/rustc_index_macros/src/newtype.rs index aaa025bd7cbdb..883d33aa8b0f7 100644 --- a/compiler/rustc_index_macros/src/newtype.rs +++ b/compiler/rustc_index_macros/src/newtype.rs @@ -161,6 +161,8 @@ impl Parse for Newtype { Some(self.cmp(other)) } } + + impl ::rustc_index::StableIdx for #name {} } } else { quote! {} diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 7c2354ebc61a1..f4ae121b36628 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -527,7 +527,11 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { .set(def_id.local_def_index, def_path_hash.local_hash().as_u64()); } } else { - for (def_index, def_key, def_path_hash) in defs.enumerated_keys_and_path_hashes() { + // FIXME DefIndex must be remapped deterministically when encoding the metadata. + // Otherwise, the parallel frontend will not produce reproducible metadata + for (def_index, def_key, def_path_hash) in + defs.unstable_enumerated_keys_and_path_hashes() + { let def_key = self.lazy(def_key); self.tables.def_keys.set_some(def_index, def_key); self.tables.def_path_hashes.set(def_index, def_path_hash.local_hash().as_u64()); diff --git a/compiler/rustc_metadata/src/rmeta/table.rs b/compiler/rustc_metadata/src/rmeta/table.rs index 811d370248dd9..8e053a0f517e7 100644 --- a/compiler/rustc_metadata/src/rmeta/table.rs +++ b/compiler/rustc_metadata/src/rmeta/table.rs @@ -1,5 +1,5 @@ use rustc_hir::def::CtorOf; -use rustc_index::Idx; +use rustc_index::{Idx, StableIdx}; use crate::rmeta::decoder::MetaBlob; use crate::rmeta::*; @@ -484,12 +484,14 @@ impl> TableBui } } } +} +impl> TableBuilder { pub(crate) fn encode(&self, buf: &mut FileEncoder<'_>) -> LazyTable { let pos = buf.position(); let width = self.width; - for block in &self.blocks { + for block in self.blocks.iter() { buf.write_with(|dest| { *dest = *block; width diff --git a/compiler/rustc_middle/src/dep_graph/serialized.rs b/compiler/rustc_middle/src/dep_graph/serialized.rs index 1c476fc91697e..50f9883b0c5a3 100644 --- a/compiler/rustc_middle/src/dep_graph/serialized.rs +++ b/compiler/rustc_middle/src/dep_graph/serialized.rs @@ -51,7 +51,7 @@ use rustc_data_structures::outline; use rustc_data_structures::profiling::SelfProfilerRef; use rustc_data_structures::sync::{AtomicU64, Lock, WorkerLocal, broadcast}; use rustc_data_structures::unhash::UnhashMap; -use rustc_index::{IndexSlice, IndexVec}; +use rustc_index::{IndexSlice, IndexVec, StableIdx}; use rustc_serialize::opaque::mem_encoder::MemEncoder; use rustc_serialize::opaque::{FileEncodeResult, FileEncoder, IntEncodedWithFixedSize, MemDecoder}; use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; @@ -71,6 +71,8 @@ rustc_index::newtype_index! { pub struct SerializedDepNodeIndex {} } +impl StableIdx for SerializedDepNodeIndex {} + impl SerializedDepNodeIndex { /// Converts a current-session dep node index to a "serialized" index, /// for the purpose of serializing data to be loaded by future sessions. diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index fd3ba5c7fe02a..a0218854e4ac0 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -1429,6 +1429,7 @@ impl<'tcx> BasicBlockData<'tcx> { rustc_index::newtype_index! { #[stable_hash] #[encodable] + #[orderable] #[debug_format = "scope[{}]"] pub struct SourceScope { const OUTERMOST_SOURCE_SCOPE = 0; diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs index 616b1719359f1..19045645b14a4 100644 --- a/compiler/rustc_middle/src/mir/query.rs +++ b/compiler/rustc_middle/src/mir/query.rs @@ -4,8 +4,8 @@ use std::fmt::{self, Debug}; use rustc_abi::{FieldIdx, VariantIdx}; use rustc_errors::ErrorGuaranteed; -use rustc_index::IndexVec; use rustc_index::bit_set::BitMatrix; +use rustc_index::{IndexVec, StableIdx}; use rustc_macros::{StableHash, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable}; use rustc_span::{Span, Symbol}; @@ -19,6 +19,8 @@ rustc_index::newtype_index! { pub struct CoroutineSavedLocal {} } +impl StableIdx for CoroutineSavedLocal {} + #[derive(Clone, Debug, PartialEq, Eq)] #[derive(TyEncodable, TyDecodable, StableHash, TypeFoldable, TypeVisitable)] pub struct CoroutineSavedTy<'tcx> { diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index e16f91f656386..8f6d758bb07a2 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -21,7 +21,7 @@ use rustc_hir as hir; use rustc_hir::attrs::AttributeKind; use rustc_hir::def_id::DefId; use rustc_hir::{BindingMode, ByRef, HirId, MatchSource, RangeEnd}; -use rustc_index::{IndexVec, newtype_index}; +use rustc_index::{IndexVec, StableIdx, newtype_index}; use rustc_macros::{StableHash, TyDecodable, TyEncodable, TypeVisitable}; use rustc_span::def_id::LocalDefId; use rustc_span::{ErrorGuaranteed, Span, Symbol}; @@ -51,6 +51,8 @@ macro_rules! thir_with_elements { #[debug_format = $format] pub struct $id {} } + + impl StableIdx for $id {} )* // Note: Making `Thir` implement `Clone` is useful for external tools that need access to diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs index 45fe03499ed6f..915dae2d2c843 100644 --- a/compiler/rustc_middle/src/ty/typeck_results.rs +++ b/compiler/rustc_middle/src/ty/typeck_results.rs @@ -12,7 +12,7 @@ use rustc_hir::{ self as hir, BindingMode, ByRef, HirId, ItemLocalId, ItemLocalMap, ItemLocalSet, Mutability, OwnerId, }; -use rustc_index::IndexVec; +use rustc_index::{IndexVec, StableIdx}; use rustc_macros::{Lift, StableHash, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable}; use rustc_session::Session; use rustc_span::Span; @@ -813,6 +813,8 @@ rustc_index::newtype_index! { } } +impl StableIdx for UserTypeAnnotationIndex {} + /// Mapping of type annotation indices to canonical user type annotations. pub type CanonicalUserTypeAnnotations<'tcx> = IndexVec>; diff --git a/compiler/rustc_mir_dataflow/src/move_paths/mod.rs b/compiler/rustc_mir_dataflow/src/move_paths/mod.rs index b6565588ae3f1..53603d3b1e79a 100644 --- a/compiler/rustc_mir_dataflow/src/move_paths/mod.rs +++ b/compiler/rustc_mir_dataflow/src/move_paths/mod.rs @@ -35,6 +35,7 @@ rustc_index::newtype_index! { rustc_index::newtype_index! { /// Index identifying an `Init`. + #[orderable] #[debug_format = "in{}"] pub struct InitIndex {} } diff --git a/compiler/rustc_mir_dataflow/src/value_analysis.rs b/compiler/rustc_mir_dataflow/src/value_analysis.rs index e213a295c0bd0..a11773649d3b0 100644 --- a/compiler/rustc_mir_dataflow/src/value_analysis.rs +++ b/compiler/rustc_mir_dataflow/src/value_analysis.rs @@ -4,8 +4,8 @@ use std::ops::Range; use rustc_abi::{FieldIdx, VariantIdx}; use rustc_data_structures::fx::{FxHashMap, FxIndexSet, StdEntry}; -use rustc_index::IndexVec; use rustc_index::bit_set::GrowableBitSet; +use rustc_index::{IndexVec, StableIdx}; use rustc_middle::mir::visit::{PlaceContext, Visitor}; use rustc_middle::mir::*; use rustc_middle::ty::{self, Ty, TyCtxt, Unnormalized}; @@ -22,11 +22,15 @@ rustc_index::newtype_index!( pub struct PlaceIndex {} ); +impl StableIdx for PlaceIndex {} + rustc_index::newtype_index!( /// This index uniquely identifies a tracked place and therefore a slot in [`State`]. pub struct ValueIndex {} ); +impl StableIdx for ValueIndex {} + /// See [`State`]. #[derive(PartialEq, Eq, Debug)] pub struct StateData { diff --git a/compiler/rustc_mir_transform/src/coverage/counters/node_flow.rs b/compiler/rustc_mir_transform/src/coverage/counters/node_flow.rs index e063f75887b3d..a6847082fcc8d 100644 --- a/compiler/rustc_mir_transform/src/coverage/counters/node_flow.rs +++ b/compiler/rustc_mir_transform/src/coverage/counters/node_flow.rs @@ -9,7 +9,7 @@ use rustc_data_structures::graph; use rustc_data_structures::union_find::UnionFind; use rustc_index::bit_set::DenseBitSet; -use rustc_index::{Idx, IndexSlice, IndexVec}; +use rustc_index::{Idx, IndexSlice, IndexVec, StableIdx}; pub(crate) use rustc_middle::mir::coverage::NodeFlowData; use rustc_middle::mir::coverage::Op; @@ -58,7 +58,7 @@ where /// influence counter allocation: /// - Earlier nodes are more likely to receive counter expressions. /// - Later nodes are more likely to receive physical counters. -pub(crate) fn make_node_counters( +pub(crate) fn make_node_counters( node_flow_data: &NodeFlowData, priority_list: &[Node], ) -> NodeCounters { @@ -126,7 +126,7 @@ struct SpantreeBuilder<'a, Node: Idx> { counter_terms: IndexVec>>, } -impl<'a, Node: Idx> SpantreeBuilder<'a, Node> { +impl<'a, Node: StableIdx> SpantreeBuilder<'a, Node> { fn new(node_flow_data: &'a NodeFlowData) -> Self { let NodeFlowData { supernodes, succ_supernodes } = node_flow_data; let num_nodes = supernodes.len(); diff --git a/compiler/rustc_mir_transform/src/dest_prop.rs b/compiler/rustc_mir_transform/src/dest_prop.rs index 7f9bba03ff345..66be712457d46 100644 --- a/compiler/rustc_mir_transform/src/dest_prop.rs +++ b/compiler/rustc_mir_transform/src/dest_prop.rs @@ -140,7 +140,7 @@ use rustc_data_structures::union_find::UnionFind; use rustc_index::bit_set::DenseBitSet; use rustc_index::interval::SparseIntervalMatrix; -use rustc_index::{IndexVec, newtype_index}; +use rustc_index::{IndexVec, StableIdx, newtype_index}; use rustc_middle::mir::visit::{MutVisitor, PlaceContext, VisitPlacesWith, Visitor}; use rustc_middle::mir::*; use rustc_middle::ty::TyCtxt; @@ -310,6 +310,8 @@ newtype_index! { struct RelevantLocal {} } +impl StableIdx for RelevantLocal {} + #[derive(Debug)] struct RelevantLocals { original: IndexVec, diff --git a/compiler/rustc_mir_transform/src/liveness.rs b/compiler/rustc_mir_transform/src/liveness.rs index 1a0d373f050a5..6e8999ff06ef2 100644 --- a/compiler/rustc_mir_transform/src/liveness.rs +++ b/compiler/rustc_mir_transform/src/liveness.rs @@ -3,8 +3,8 @@ use rustc_data_structures::fx::{FxHashSet, FxIndexMap, IndexEntry}; use rustc_hir::def::{CtorKind, DefKind}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::find_attr; -use rustc_index::IndexVec; use rustc_index::bit_set::DenseBitSet; +use rustc_index::{IndexVec, StableIdx}; use rustc_lint_defs::builtin::{UNUSED_ASSIGNMENTS, UNUSED_VARIABLES}; use rustc_middle::bug; use rustc_middle::mir::visit::{ @@ -1286,6 +1286,8 @@ rustc_index::newtype_index! { pub struct PlaceIndex {} } +impl StableIdx for PlaceIndex {} + impl DebugWithContext> for PlaceIndex { fn fmt_with( &self, diff --git a/compiler/rustc_mir_transform/src/prettify.rs b/compiler/rustc_mir_transform/src/prettify.rs index f86ad4d49e769..4054f764cd363 100644 --- a/compiler/rustc_mir_transform/src/prettify.rs +++ b/compiler/rustc_mir_transform/src/prettify.rs @@ -92,7 +92,9 @@ fn permute(data: &mut IndexVec, map: &IndexS // FIXME: It would be nice to have a less-awkward way to apply permutations, // but I don't know one that exists. `sort_by_cached_key` has logic for it // internally, but not in a way that we're allowed to use here. - let mut enumerated: Vec<_> = std::mem::take(data).into_iter_enumerated().collect(); + // + // its ok to use `unstable_into_iter_enumerated` here since we are sorting right after + let mut enumerated: Vec<_> = std::mem::take(data).unstable_into_iter_enumerated().collect(); enumerated.sort_by_key(|p| map[p.0]); *data = enumerated.into_iter().map(|p| p.1).collect(); } diff --git a/compiler/rustc_monomorphize/src/graph_checks/statics.rs b/compiler/rustc_monomorphize/src/graph_checks/statics.rs index 4a6416843fded..2e7f74ad3852f 100644 --- a/compiler/rustc_monomorphize/src/graph_checks/statics.rs +++ b/compiler/rustc_monomorphize/src/graph_checks/statics.rs @@ -3,7 +3,7 @@ use rustc_data_structures::graph::scc::Sccs; use rustc_data_structures::graph::{DirectedGraph, Successors}; use rustc_data_structures::unord::UnordMap; use rustc_hir::def_id::DefId; -use rustc_index::{Idx, IndexVec, newtype_index}; +use rustc_index::{Idx, IndexVec, StableIdx, newtype_index}; use rustc_middle::mono::MonoItem; use rustc_middle::ty::TyCtxt; @@ -23,6 +23,8 @@ impl Idx for StaticNodeIdx { } } +impl StableIdx for StaticNodeIdx {} + impl From for StaticNodeIdx { fn from(value: usize) -> Self { StaticNodeIdx(value) diff --git a/compiler/rustc_pattern_analysis/src/lib.rs b/compiler/rustc_pattern_analysis/src/lib.rs index f17375ea47c5f..d6d2b941a4115 100644 --- a/compiler/rustc_pattern_analysis/src/lib.rs +++ b/compiler/rustc_pattern_analysis/src/lib.rs @@ -20,6 +20,7 @@ pub mod usefulness; use std::fmt; +use rustc_index::StableIdx; pub use rustc_index::{Idx, IndexVec}; // re-exported to avoid rustc_index version issues use crate::constructor::{Constructor, ConstructorSet, IntRange}; @@ -39,7 +40,7 @@ pub trait PatCx: Sized + fmt::Debug { /// Errors that can abort analysis. type Error: fmt::Debug; /// The index of an enum variant. - type VariantIdx: Clone + Idx + fmt::Debug; + type VariantIdx: Clone + StableIdx + fmt::Debug; /// A string literal type StrLit: Clone + PartialEq + fmt::Debug; /// Extra data to store in a match arm. diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs index 3ca3fd0940f7f..c8f38e0243c01 100644 --- a/compiler/rustc_span/src/hygiene.rs +++ b/compiler/rustc_span/src/hygiene.rs @@ -674,7 +674,8 @@ pub fn debug_hygiene_data(verbose: bool) -> String { expn_data.kind, )) }; - data.local_expn_data.iter_enumerated().for_each(|(id, expn_data)| { + // its ok to use `unstable_iter_enumerated` iter here, as this is just for debug formatting + data.local_expn_data.unstable_iter_enumerated().for_each(|(id, expn_data)| { let expn_data = expn_data.as_ref().expect("no expansion data for an expansion ID"); debug_expn_data((&id.to_expn_id(), expn_data)) }); diff --git a/compiler/rustc_type_ir/src/fold.rs b/compiler/rustc_type_ir/src/fold.rs index 2b25de4132e62..3bbabc4d7104b 100644 --- a/compiler/rustc_type_ir/src/fold.rs +++ b/compiler/rustc_type_ir/src/fold.rs @@ -49,7 +49,7 @@ use std::convert::Infallible; use std::mem; use std::sync::Arc; -use rustc_index::{Idx, IndexVec}; +use rustc_index::{IndexVec, StableIdx}; use thin_vec::ThinVec; use tracing::{debug, instrument}; @@ -379,7 +379,7 @@ impl> TypeFoldable for Box<[T]> { } } -impl, Ix: Idx> TypeFoldable for IndexVec { +impl, Ix: StableIdx> TypeFoldable for IndexVec { fn try_fold_with>(self, folder: &mut F) -> Result { self.raw.try_fold_with(folder).map(IndexVec::from_raw) } diff --git a/compiler/rustc_type_ir/src/generic_visit.rs b/compiler/rustc_type_ir/src/generic_visit.rs index 2444990749411..96220d7feeb89 100644 --- a/compiler/rustc_type_ir/src/generic_visit.rs +++ b/compiler/rustc_type_ir/src/generic_visit.rs @@ -11,7 +11,7 @@ use std::sync::Arc; -use rustc_index::{Idx, IndexVec}; +use rustc_index::{IndexVec, StableIdx}; use smallvec::SmallVec; use thin_vec::ThinVec; @@ -116,7 +116,9 @@ unsafe impl> GenericTypeVisitable for [T] { } } -unsafe impl, Ix: Idx> GenericTypeVisitable for IndexVec { +unsafe impl, Ix: StableIdx> GenericTypeVisitable + for IndexVec +{ fn generic_visit_with(&self, visitor: &mut V) { self.iter().for_each(|it| it.generic_visit_with(visitor)); } diff --git a/compiler/rustc_type_ir/src/visit.rs b/compiler/rustc_type_ir/src/visit.rs index 1138d8cf9edad..d783e40e16a98 100644 --- a/compiler/rustc_type_ir/src/visit.rs +++ b/compiler/rustc_type_ir/src/visit.rs @@ -47,7 +47,7 @@ use std::sync::Arc; pub use rustc_ast_ir::visit::VisitorResult; pub use rustc_ast_ir::{try_visit, walk_visitable_list}; -use rustc_index::{Idx, IndexVec}; +use rustc_index::{IndexVec, StableIdx}; use smallvec::SmallVec; use thin_vec::ThinVec; @@ -223,7 +223,7 @@ impl> TypeVisitable for [T; } } -impl, Ix: Idx> TypeVisitable for IndexVec { +impl, Ix: StableIdx> TypeVisitable for IndexVec { fn visit_with>(&self, visitor: &mut V) -> V::Result { walk_visitable_list!(visitor, self.iter()); V::Result::output()