From df8fe7dd34244b972cd9c4f7935fe8d6e1ea50db Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 6 May 2024 13:04:33 +1000 Subject: [PATCH 1/7] Remove `macro_use` from `stable_hasher`. Normal `use` items are nicer. --- compiler/rustc_data_structures/src/fingerprint.rs | 1 + compiler/rustc_data_structures/src/lib.rs | 7 +++---- compiler/rustc_data_structures/src/stable_hasher.rs | 2 ++ 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_data_structures/src/fingerprint.rs b/compiler/rustc_data_structures/src/fingerprint.rs index 9995c08345c..1bee159489d 100644 --- a/compiler/rustc_data_structures/src/fingerprint.rs +++ b/compiler/rustc_data_structures/src/fingerprint.rs @@ -1,3 +1,4 @@ +use crate::stable_hasher::impl_stable_traits_for_trivial_type; use crate::stable_hasher::{Hash64, StableHasher, StableHasherResult}; use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; use std::hash::{Hash, Hasher}; diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs index 8dd85b25e0e..6784c73b790 100644 --- a/compiler/rustc_data_structures/src/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -72,15 +72,14 @@ pub mod small_c_str; pub mod snapshot_map; pub mod svh; pub use ena::snapshot_vec; -pub mod memmap; -pub mod sorted_map; -#[macro_use] -pub mod stable_hasher; mod atomic_ref; pub mod fingerprint; pub mod marker; +pub mod memmap; pub mod profiling; pub mod sharded; +pub mod sorted_map; +pub mod stable_hasher; pub mod stack; pub mod sync; pub mod tiny_list; diff --git a/compiler/rustc_data_structures/src/stable_hasher.rs b/compiler/rustc_data_structures/src/stable_hasher.rs index 8418b4bbd47..b5bdf2e1790 100644 --- a/compiler/rustc_data_structures/src/stable_hasher.rs +++ b/compiler/rustc_data_structures/src/stable_hasher.rs @@ -296,6 +296,8 @@ macro_rules! impl_stable_traits_for_trivial_type { }; } +pub(crate) use impl_stable_traits_for_trivial_type; + impl_stable_traits_for_trivial_type!(i8); impl_stable_traits_for_trivial_type!(i16); impl_stable_traits_for_trivial_type!(i32); From 351c0fa2a33baa3406a0c00034ff5e2cdac6fd7f Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 6 May 2024 13:17:19 +1000 Subject: [PATCH 2/7] Reorder top-level crate items. - `use` before `mod` - `pub` before `non-pub` - Alphabetical order within sections --- compiler/rustc_data_structures/src/lib.rs | 94 +++++++++++------------ 1 file changed, 47 insertions(+), 47 deletions(-) diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs index 6784c73b790..5ea97827277 100644 --- a/compiler/rustc_data_structures/src/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -45,9 +45,55 @@ #[macro_use] extern crate tracing; +pub use atomic_ref::AtomicRef; +pub use ena::snapshot_vec; +pub use ena::undo_log; +pub use ena::unify; +pub use rustc_index::static_assert_size; + use std::fmt; -pub use rustc_index::static_assert_size; +pub mod aligned; +pub mod base_n; +pub mod binary_search_util; +pub mod captures; +pub mod fingerprint; +pub mod flat_map_in_place; +pub mod flock; +pub mod frozen; +pub mod fx; +pub mod graph; +pub mod intern; +pub mod jobserver; +pub mod macros; +pub mod marker; +pub mod memmap; +pub mod obligation_forest; +pub mod owned_slice; +pub mod packed; +pub mod profiling; +pub mod sharded; +pub mod sip128; +pub mod small_c_str; +pub mod snapshot_map; +pub mod sorted_map; +pub mod sso; +pub mod stable_hasher; +pub mod stack; +pub mod steal; +pub mod svh; +pub mod sync; +pub mod tagged_ptr; +pub mod temp_dir; +pub mod tiny_list; +pub mod transitive_relation; +pub mod unhash; +pub mod unord; +pub mod vec_linked_list; +pub mod work_queue; + +mod atomic_ref; +mod hashes; /// This calls the passed function while ensuring it won't be inlined into the caller. #[inline(never)] @@ -56,52 +102,6 @@ pub fn outline R, R>(f: F) -> R { f() } -pub mod base_n; -pub mod binary_search_util; -pub mod captures; -pub mod flat_map_in_place; -pub mod flock; -pub mod fx; -pub mod graph; -pub mod intern; -pub mod jobserver; -pub mod macros; -pub mod obligation_forest; -pub mod sip128; -pub mod small_c_str; -pub mod snapshot_map; -pub mod svh; -pub use ena::snapshot_vec; -mod atomic_ref; -pub mod fingerprint; -pub mod marker; -pub mod memmap; -pub mod profiling; -pub mod sharded; -pub mod sorted_map; -pub mod stable_hasher; -pub mod stack; -pub mod sync; -pub mod tiny_list; -pub mod transitive_relation; -pub mod vec_linked_list; -pub mod work_queue; -pub use atomic_ref::AtomicRef; -pub mod aligned; -pub mod frozen; -mod hashes; -pub mod owned_slice; -pub mod packed; -pub mod sso; -pub mod steal; -pub mod tagged_ptr; -pub mod temp_dir; -pub mod unhash; -pub mod unord; - -pub use ena::undo_log; -pub use ena::unify; - /// Returns a structure that calls `f` when dropped. pub fn defer(f: F) -> OnDrop { OnDrop(Some(f)) From 55b6ff8e41739404b0a6fb23e7f8fbff615a900d Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 6 May 2024 13:35:41 +1000 Subject: [PATCH 3/7] Remove `extern crate tracing`. `use` is a nicer way of doing things. --- compiler/rustc_data_structures/src/flock/windows.rs | 1 + compiler/rustc_data_structures/src/graph/implementation/mod.rs | 1 + .../rustc_data_structures/src/graph/implementation/tests.rs | 1 + compiler/rustc_data_structures/src/graph/scc/mod.rs | 1 + compiler/rustc_data_structures/src/lib.rs | 3 --- compiler/rustc_data_structures/src/obligation_forest/mod.rs | 2 +- compiler/rustc_data_structures/src/profiling.rs | 1 + 7 files changed, 6 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_data_structures/src/flock/windows.rs b/compiler/rustc_data_structures/src/flock/windows.rs index 9be1065135a..7dc72661939 100644 --- a/compiler/rustc_data_structures/src/flock/windows.rs +++ b/compiler/rustc_data_structures/src/flock/windows.rs @@ -2,6 +2,7 @@ use std::fs::{File, OpenOptions}; use std::io; use std::os::windows::prelude::*; use std::path::Path; +use tracing::debug; use windows::{ Win32::Foundation::{ERROR_INVALID_FUNCTION, HANDLE}, diff --git a/compiler/rustc_data_structures/src/graph/implementation/mod.rs b/compiler/rustc_data_structures/src/graph/implementation/mod.rs index 3910c6fa46d..8cf4b4153db 100644 --- a/compiler/rustc_data_structures/src/graph/implementation/mod.rs +++ b/compiler/rustc_data_structures/src/graph/implementation/mod.rs @@ -22,6 +22,7 @@ use rustc_index::bit_set::BitSet; use std::fmt::Debug; +use tracing::debug; #[cfg(test)] mod tests; diff --git a/compiler/rustc_data_structures/src/graph/implementation/tests.rs b/compiler/rustc_data_structures/src/graph/implementation/tests.rs index 3ae5f5868f0..b4dbd65db94 100644 --- a/compiler/rustc_data_structures/src/graph/implementation/tests.rs +++ b/compiler/rustc_data_structures/src/graph/implementation/tests.rs @@ -1,4 +1,5 @@ use crate::graph::implementation::*; +use tracing::debug; type TestGraph = Graph<&'static str, &'static str>; diff --git a/compiler/rustc_data_structures/src/graph/scc/mod.rs b/compiler/rustc_data_structures/src/graph/scc/mod.rs index 5021e5e8fc0..914a6a16348 100644 --- a/compiler/rustc_data_structures/src/graph/scc/mod.rs +++ b/compiler/rustc_data_structures/src/graph/scc/mod.rs @@ -10,6 +10,7 @@ use crate::graph::vec_graph::VecGraph; use crate::graph::{DirectedGraph, NumEdges, Successors}; use rustc_index::{Idx, IndexSlice, IndexVec}; use std::ops::Range; +use tracing::{debug, instrument}; #[cfg(test)] mod tests; diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs index 5ea97827277..b455cbeded9 100644 --- a/compiler/rustc_data_structures/src/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -42,9 +42,6 @@ #![feature(unwrap_infallible)] // tidy-alphabetical-end -#[macro_use] -extern crate tracing; - pub use atomic_ref::AtomicRef; pub use ena::snapshot_vec; pub use ena::undo_log; diff --git a/compiler/rustc_data_structures/src/obligation_forest/mod.rs b/compiler/rustc_data_structures/src/obligation_forest/mod.rs index a47908648ba..d477b86da74 100644 --- a/compiler/rustc_data_structures/src/obligation_forest/mod.rs +++ b/compiler/rustc_data_structures/src/obligation_forest/mod.rs @@ -70,12 +70,12 @@ //! aren't needed anymore. use crate::fx::{FxHashMap, FxHashSet}; - use std::cell::Cell; use std::collections::hash_map::Entry; use std::fmt::Debug; use std::hash; use std::marker::PhantomData; +use tracing::debug; mod graphviz; diff --git a/compiler/rustc_data_structures/src/profiling.rs b/compiler/rustc_data_structures/src/profiling.rs index 2569684df3f..c6d51a5d6b4 100644 --- a/compiler/rustc_data_structures/src/profiling.rs +++ b/compiler/rustc_data_structures/src/profiling.rs @@ -99,6 +99,7 @@ pub use measureme::EventId; use measureme::{EventIdBuilder, Profiler, SerializableString, StringId}; use parking_lot::RwLock; use smallvec::SmallVec; +use tracing::warn; bitflags::bitflags! { #[derive(Clone, Copy)] From d7814e72ebe3b4a293a5f91fa1648d2ef72639d3 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 6 May 2024 15:36:46 +1000 Subject: [PATCH 4/7] Document `Pu128`. And move the `repr` line after the `derive` line, where it's harder to overlook. (I overlooked it initially, and didn't understand how this type worked.) --- compiler/rustc_data_structures/src/packed.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_data_structures/src/packed.rs b/compiler/rustc_data_structures/src/packed.rs index b8d4b295dfa..0a392d91988 100644 --- a/compiler/rustc_data_structures/src/packed.rs +++ b/compiler/rustc_data_structures/src/packed.rs @@ -3,8 +3,10 @@ use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; use std::cmp::Ordering; use std::fmt; -#[repr(packed(8))] +/// A packed 128-bit integer. Useful for reducing the size of structures in +/// some cases. #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[repr(packed(8))] pub struct Pu128(pub u128); impl Pu128 { From f5d7d346a48b75ef566674fca05cd4b29a985678 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 7 May 2024 08:05:02 +1000 Subject: [PATCH 5/7] Remove `TinyList`. It is optimized for lists with a single element, avoiding the need for an allocation in that case. But `SmallVec<[T; 1]>` also avoids the allocation, and is better in general: more standard, log2 number of allocations if the list exceeds one item, and a much more capable API. This commit removes `TinyList` and converts the two uses to `SmallVec<[T; 1]>`. It also reorders the `use` items in the relevant file so they are in just two sections (`pub` and non-`pub`), ordered alphabetically, instead of many sections. (This is a relevant part of the change because I had to decide where to add a `use` item for `SmallVec`.) --- compiler/rustc_data_structures/src/lib.rs | 1 - .../rustc_data_structures/src/tiny_list.rs | 80 --------- .../src/tiny_list/tests.rs | 155 ------------------ .../rustc_middle/src/mir/interpret/mod.rs | 17 +- 4 files changed, 8 insertions(+), 245 deletions(-) delete mode 100644 compiler/rustc_data_structures/src/tiny_list.rs delete mode 100644 compiler/rustc_data_structures/src/tiny_list/tests.rs diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs index b455cbeded9..2e5f3806b12 100644 --- a/compiler/rustc_data_structures/src/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -82,7 +82,6 @@ pub mod svh; pub mod sync; pub mod tagged_ptr; pub mod temp_dir; -pub mod tiny_list; pub mod transitive_relation; pub mod unhash; pub mod unord; diff --git a/compiler/rustc_data_structures/src/tiny_list.rs b/compiler/rustc_data_structures/src/tiny_list.rs deleted file mode 100644 index 11a408f216a..00000000000 --- a/compiler/rustc_data_structures/src/tiny_list.rs +++ /dev/null @@ -1,80 +0,0 @@ -//! A singly-linked list. -//! -//! Using this data structure only makes sense under very specific -//! circumstances: -//! -//! - If you have a list that rarely stores more than one element, then this -//! data-structure can store the element without allocating and only uses as -//! much space as an `Option<(T, usize)>`. If T can double as the `Option` -//! discriminant, it will even only be as large as `T, usize`. -//! -//! If you expect to store more than 1 element in the common case, steer clear -//! and use a `Vec`, `Box<[T]>`, or a `SmallVec`. - -#[cfg(test)] -mod tests; - -#[derive(Clone)] -pub struct TinyList { - head: Option>, -} - -impl TinyList { - #[inline] - pub fn new() -> TinyList { - TinyList { head: None } - } - - #[inline] - pub fn new_single(data: T) -> TinyList { - TinyList { head: Some(Element { data, next: None }) } - } - - #[inline] - pub fn insert(&mut self, data: T) { - self.head = Some(Element { data, next: self.head.take().map(Box::new) }); - } - - #[inline] - pub fn remove(&mut self, data: &T) -> bool { - self.head = match &mut self.head { - Some(head) if head.data == *data => head.next.take().map(|x| *x), - Some(head) => return head.remove_next(data), - None => return false, - }; - true - } - - #[inline] - pub fn contains(&self, data: &T) -> bool { - let mut elem = self.head.as_ref(); - while let Some(e) = elem { - if &e.data == data { - return true; - } - elem = e.next.as_deref(); - } - false - } -} - -#[derive(Clone)] -struct Element { - data: T, - next: Option>>, -} - -impl Element { - fn remove_next(mut self: &mut Self, data: &T) -> bool { - loop { - match self.next { - Some(ref mut next) if next.data == *data => { - self.next = next.next.take(); - return true; - } - Some(ref mut next) => self = next, - None => return false, - } - } - } -} diff --git a/compiler/rustc_data_structures/src/tiny_list/tests.rs b/compiler/rustc_data_structures/src/tiny_list/tests.rs deleted file mode 100644 index 4b95e62bef0..00000000000 --- a/compiler/rustc_data_structures/src/tiny_list/tests.rs +++ /dev/null @@ -1,155 +0,0 @@ -use super::*; - -extern crate test; -use test::{black_box, Bencher}; - -impl TinyList { - fn len(&self) -> usize { - let (mut elem, mut count) = (self.head.as_ref(), 0); - while let Some(e) = elem { - count += 1; - elem = e.next.as_deref(); - } - count - } -} - -#[test] -fn test_contains_and_insert() { - fn do_insert(i: u32) -> bool { - i % 2 == 0 - } - - let mut list = TinyList::new(); - - for i in 0..10 { - for j in 0..i { - if do_insert(j) { - assert!(list.contains(&j)); - } else { - assert!(!list.contains(&j)); - } - } - - assert!(!list.contains(&i)); - - if do_insert(i) { - list.insert(i); - assert!(list.contains(&i)); - } - } -} - -#[test] -fn test_remove_first() { - let mut list = TinyList::new(); - list.insert(1); - list.insert(2); - list.insert(3); - list.insert(4); - assert_eq!(list.len(), 4); - - assert!(list.remove(&4)); - assert!(!list.contains(&4)); - - assert_eq!(list.len(), 3); - assert!(list.contains(&1)); - assert!(list.contains(&2)); - assert!(list.contains(&3)); -} - -#[test] -fn test_remove_last() { - let mut list = TinyList::new(); - list.insert(1); - list.insert(2); - list.insert(3); - list.insert(4); - assert_eq!(list.len(), 4); - - assert!(list.remove(&1)); - assert!(!list.contains(&1)); - - assert_eq!(list.len(), 3); - assert!(list.contains(&2)); - assert!(list.contains(&3)); - assert!(list.contains(&4)); -} - -#[test] -fn test_remove_middle() { - let mut list = TinyList::new(); - list.insert(1); - list.insert(2); - list.insert(3); - list.insert(4); - assert_eq!(list.len(), 4); - - assert!(list.remove(&2)); - assert!(!list.contains(&2)); - - assert_eq!(list.len(), 3); - assert!(list.contains(&1)); - assert!(list.contains(&3)); - assert!(list.contains(&4)); -} - -#[test] -fn test_remove_single() { - let mut list = TinyList::new(); - list.insert(1); - assert_eq!(list.len(), 1); - - assert!(list.remove(&1)); - assert!(!list.contains(&1)); - - assert_eq!(list.len(), 0); -} - -#[bench] -fn bench_insert_empty(b: &mut Bencher) { - b.iter(|| { - let mut list = black_box(TinyList::new()); - list.insert(1); - list - }) -} - -#[bench] -fn bench_insert_one(b: &mut Bencher) { - b.iter(|| { - let mut list = black_box(TinyList::new_single(0)); - list.insert(1); - list - }) -} - -#[bench] -fn bench_contains_empty(b: &mut Bencher) { - b.iter(|| black_box(TinyList::new()).contains(&1)); -} - -#[bench] -fn bench_contains_unknown(b: &mut Bencher) { - b.iter(|| black_box(TinyList::new_single(0)).contains(&1)); -} - -#[bench] -fn bench_contains_one(b: &mut Bencher) { - b.iter(|| black_box(TinyList::new_single(1)).contains(&1)); -} - -#[bench] -fn bench_remove_empty(b: &mut Bencher) { - b.iter(|| black_box(TinyList::new()).remove(&1)); -} - -#[bench] -fn bench_remove_unknown(b: &mut Bencher) { - b.iter(|| black_box(TinyList::new_single(0)).remove(&1)); -} - -#[bench] -fn bench_remove_one(b: &mut Bencher) { - b.iter(|| black_box(TinyList::new_single(1)).remove(&1)); -} diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs index ee3cdf36820..38cb1d5f9a0 100644 --- a/compiler/rustc_middle/src/mir/interpret/mod.rs +++ b/compiler/rustc_middle/src/mir/interpret/mod.rs @@ -125,10 +125,11 @@ use std::io::{Read, Write}; use std::num::NonZero; use std::sync::atomic::{AtomicU32, Ordering}; +use smallvec::{smallvec, SmallVec}; + use rustc_ast::LitKind; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::{HashMapExt, Lock}; -use rustc_data_structures::tiny_list::TinyList; use rustc_errors::ErrorGuaranteed; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable}; @@ -266,8 +267,8 @@ type DecodingSessionId = NonZero; #[derive(Clone)] enum State { Empty, - InProgressNonAlloc(TinyList), - InProgress(TinyList, AllocId), + InProgressNonAlloc(SmallVec<[DecodingSessionId; 1]>), + InProgress(SmallVec<[DecodingSessionId; 1]>, AllocId), Done(AllocId), } @@ -337,8 +338,7 @@ impl<'s> AllocDecodingSession<'s> { // If this is an allocation, we need to reserve an // `AllocId` so we can decode cyclic graphs. let alloc_id = decoder.interner().reserve_alloc_id(); - *entry = - State::InProgress(TinyList::new_single(self.session_id), alloc_id); + *entry = State::InProgress(smallvec![self.session_id], alloc_id); Some(alloc_id) } AllocDiscriminant::Fn @@ -346,8 +346,7 @@ impl<'s> AllocDecodingSession<'s> { | AllocDiscriminant::VTable => { // Fns and statics cannot be cyclic, and their `AllocId` // is determined later by interning. - *entry = - State::InProgressNonAlloc(TinyList::new_single(self.session_id)); + *entry = State::InProgressNonAlloc(smallvec![self.session_id]); None } } @@ -357,7 +356,7 @@ impl<'s> AllocDecodingSession<'s> { bug!("this should be unreachable"); } else { // Start decoding concurrently. - sessions.insert(self.session_id); + sessions.push(self.session_id); None } } @@ -367,7 +366,7 @@ impl<'s> AllocDecodingSession<'s> { return alloc_id; } else { // Start decoding concurrently. - sessions.insert(self.session_id); + sessions.push(self.session_id); Some(alloc_id) } } From d3d01e1cd3a4157692e136f3a1f8e0a5e37f3e36 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 7 May 2024 09:35:50 +1000 Subject: [PATCH 6/7] Remove `vec_linked_list`. It provides a way to effectively embed a linked list within an `IndexVec` and also iterate over that list. It's written in a very generic way, involving two traits `Links` and `LinkElem`. But the `Links` trait is only impl'd for `IndexVec` and `&IndexVec`, and the whole thing is only used in one module within `rustc_borrowck`. So I think it's over-engineered and hard to read. Plus it has no comments. This commit removes it, and adds a (non-generic) local iterator for the use within `rustc_borrowck`. Much simpler. --- .../src/type_check/liveness/local_use_map.rs | 42 ++++++++--- compiler/rustc_data_structures/src/lib.rs | 1 - .../src/vec_linked_list.rs | 70 ------------------- 3 files changed, 32 insertions(+), 81 deletions(-) delete mode 100644 compiler/rustc_data_structures/src/vec_linked_list.rs diff --git a/compiler/rustc_borrowck/src/type_check/liveness/local_use_map.rs b/compiler/rustc_borrowck/src/type_check/liveness/local_use_map.rs index da5456692ab..ccd9fb25739 100644 --- a/compiler/rustc_borrowck/src/type_check/liveness/local_use_map.rs +++ b/compiler/rustc_borrowck/src/type_check/liveness/local_use_map.rs @@ -1,4 +1,3 @@ -use rustc_data_structures::vec_linked_list as vll; use rustc_index::IndexVec; use rustc_middle::mir::visit::{PlaceContext, Visitor}; use rustc_middle::mir::{Body, Local, Location}; @@ -37,9 +36,12 @@ pub(crate) struct LocalUseMap { /// we add for each local variable. first_drop_at: IndexVec>, - appearances: IndexVec, + appearances: Appearances, } +// The `Appearance::next` field effectively embeds a linked list within `Appearances`. +type Appearances = IndexVec; + struct Appearance { point_index: PointIndex, next: Option, @@ -49,14 +51,34 @@ rustc_index::newtype_index! { pub struct AppearanceIndex {} } -impl vll::LinkElem for Appearance { - type LinkIndex = AppearanceIndex; +fn appearances_iter( + first: Option, + appearances: &Appearances, +) -> impl Iterator + '_ { + AppearancesIter { appearances, current: first } +} - fn next(elem: &Self) -> Option { - elem.next +// Iterates over `Appearances` by following `next` fields. +struct AppearancesIter<'a> { + appearances: &'a Appearances, + current: Option, +} + +impl<'a> Iterator for AppearancesIter<'a> { + type Item = AppearanceIndex; + + fn next(&mut self) -> Option { + if let Some(c) = self.current { + self.current = self.appearances[c].next; + Some(c) + } else { + None + } } } +//----------------------------------------------------------------------------- + impl LocalUseMap { pub(crate) fn build( live_locals: &[Local], @@ -86,17 +108,17 @@ impl LocalUseMap { } pub(crate) fn defs(&self, local: Local) -> impl Iterator + '_ { - vll::iter(self.first_def_at[local], &self.appearances) + appearances_iter(self.first_def_at[local], &self.appearances) .map(move |aa| self.appearances[aa].point_index) } pub(crate) fn uses(&self, local: Local) -> impl Iterator + '_ { - vll::iter(self.first_use_at[local], &self.appearances) + appearances_iter(self.first_use_at[local], &self.appearances) .map(move |aa| self.appearances[aa].point_index) } pub(crate) fn drops(&self, local: Local) -> impl Iterator + '_ { - vll::iter(self.first_drop_at[local], &self.appearances) + appearances_iter(self.first_drop_at[local], &self.appearances) .map(move |aa| self.appearances[aa].point_index) } } @@ -146,7 +168,7 @@ impl LocalUseMapBuild<'_> { fn insert( elements: &DenseLocationMap, first_appearance: &mut Option, - appearances: &mut IndexVec, + appearances: &mut Appearances, location: Location, ) { let point_index = elements.point_from_location(location); diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs index 2e5f3806b12..407ee0453e5 100644 --- a/compiler/rustc_data_structures/src/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -85,7 +85,6 @@ pub mod temp_dir; pub mod transitive_relation; pub mod unhash; pub mod unord; -pub mod vec_linked_list; pub mod work_queue; mod atomic_ref; diff --git a/compiler/rustc_data_structures/src/vec_linked_list.rs b/compiler/rustc_data_structures/src/vec_linked_list.rs deleted file mode 100644 index fda72c9a3b2..00000000000 --- a/compiler/rustc_data_structures/src/vec_linked_list.rs +++ /dev/null @@ -1,70 +0,0 @@ -use rustc_index::{Idx, IndexVec}; - -pub fn iter( - first: Option, - links: &Ls, -) -> impl Iterator + '_ -where - Ls: Links, -{ - VecLinkedListIterator { links, current: first } -} - -pub struct VecLinkedListIterator -where - Ls: Links, -{ - links: Ls, - current: Option, -} - -impl Iterator for VecLinkedListIterator -where - Ls: Links, -{ - type Item = Ls::LinkIndex; - - fn next(&mut self) -> Option { - if let Some(c) = self.current { - self.current = ::next(&self.links, c); - Some(c) - } else { - None - } - } -} - -pub trait Links { - type LinkIndex: Copy; - - fn next(links: &Self, index: Self::LinkIndex) -> Option; -} - -impl Links for &Ls -where - Ls: Links, -{ - type LinkIndex = Ls::LinkIndex; - - fn next(links: &Self, index: Ls::LinkIndex) -> Option { - ::next(links, index) - } -} - -pub trait LinkElem { - type LinkIndex: Copy; - - fn next(elem: &Self) -> Option; -} - -impl Links for IndexVec -where - E: LinkElem, - L: Idx, -{ - type LinkIndex = L; - - fn next(links: &Self, index: L) -> Option { - ::next(&links[index]) - } -} From 58a06b6a9986149937d7efa97eba83df207a1c7c Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 6 May 2024 13:51:15 +1000 Subject: [PATCH 7/7] Remove `enum_from_u32`. It's a macro that just creates an enum with a `from_u32` method. It has two arms. One is unused and the other has a single use. This commit inlines that single use and removes the whole macro. This increases readability because we don't have two different macros interacting (`enum_from_u32` and `language_item_table`). --- compiler/rustc_data_structures/src/lib.rs | 1 - compiler/rustc_data_structures/src/macros.rs | 37 -------------------- compiler/rustc_hir/src/lang_items.rs | 32 ++++++++++------- 3 files changed, 19 insertions(+), 51 deletions(-) delete mode 100644 compiler/rustc_data_structures/src/macros.rs diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs index 407ee0453e5..85b5a3cdb7c 100644 --- a/compiler/rustc_data_structures/src/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -62,7 +62,6 @@ pub mod fx; pub mod graph; pub mod intern; pub mod jobserver; -pub mod macros; pub mod marker; pub mod memmap; pub mod obligation_forest; diff --git a/compiler/rustc_data_structures/src/macros.rs b/compiler/rustc_data_structures/src/macros.rs deleted file mode 100644 index e05491f6ff6..00000000000 --- a/compiler/rustc_data_structures/src/macros.rs +++ /dev/null @@ -1,37 +0,0 @@ -#[macro_export] -macro_rules! enum_from_u32 { - ($(#[$attr:meta])* pub enum $name:ident { - $($(#[$var_attr:meta])* $variant:ident = $e:expr,)* - }) => { - $(#[$attr])* - pub enum $name { - $($(#[$var_attr])* $variant = $e),* - } - - impl $name { - pub fn from_u32(u: u32) -> Option<$name> { - $(if u == $name::$variant as u32 { - return Some($name::$variant) - })* - None - } - } - }; - ($(#[$attr:meta])* pub enum $name:ident { - $($(#[$var_attr:meta])* $variant:ident,)* - }) => { - $(#[$attr])* - pub enum $name { - $($(#[$var_attr])* $variant,)* - } - - impl $name { - pub fn from_u32(u: u32) -> Option<$name> { - $(if u == $name::$variant as u32 { - return Some($name::$variant) - })* - None - } - } - } -} diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index e870a04127a..c4be67cdd88 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -55,21 +55,27 @@ macro_rules! language_item_table { ( $( $(#[$attr:meta])* $variant:ident, $module:ident :: $name:ident, $method:ident, $target:expr, $generics:expr; )* ) => { - - rustc_data_structures::enum_from_u32! { - /// A representation of all the valid lang items in Rust. - #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable)] - pub enum LangItem { - $( - #[doc = concat!("The `", stringify!($name), "` lang item.")] - /// - $(#[$attr])* - $variant, - )* - } + /// A representation of all the valid lang items in Rust. + #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable)] + pub enum LangItem { + $( + #[doc = concat!("The `", stringify!($name), "` lang item.")] + $(#[$attr])* + $variant, + )* } impl LangItem { + fn from_u32(u: u32) -> Option { + // This implementation is clumsy, but makes no assumptions + // about how discriminant tags are allocated within the + // range `0 .. std::mem::variant_count::()`. + $(if u == LangItem::$variant as u32 { + return Some(LangItem::$variant) + })* + None + } + /// Returns the `name` symbol in `#[lang = "$name"]`. /// For example, [`LangItem::PartialEq`]`.name()` /// would result in [`sym::eq`] since it is `#[lang = "eq"]`. @@ -147,7 +153,7 @@ language_item_table! { Clone, sym::clone, clone_trait, Target::Trait, GenericRequirement::None; Sync, sym::sync, sync_trait, Target::Trait, GenericRequirement::Exact(0); DiscriminantKind, sym::discriminant_kind, discriminant_kind_trait, Target::Trait, GenericRequirement::None; - /// The associated item of the [`DiscriminantKind`] trait. + /// The associated item of the `DiscriminantKind` trait. Discriminant, sym::discriminant_type, discriminant_type, Target::AssocTy, GenericRequirement::None; PointeeTrait, sym::pointee_trait, pointee_trait, Target::Trait, GenericRequirement::None;