From be321858102aae9a0774dfb8afb128c27c5f2640 Mon Sep 17 00:00:00 2001 From: csmoe Date: Thu, 26 Sep 2019 02:55:18 +0800 Subject: init librustc_index crate --- src/librustc_index/Cargo.toml | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 src/librustc_index/Cargo.toml diff --git a/src/librustc_index/Cargo.toml b/src/librustc_index/Cargo.toml new file mode 100644 index 00000000000..f3d837c73b8 --- /dev/null +++ b/src/librustc_index/Cargo.toml @@ -0,0 +1,12 @@ +[package] +authors = ["The Rust Project Developers"] +name = "rustc_index" +version = "0.0.0" +edition = "2018" + +[lib] +name = "rustc_index" +path = "lib.rs" +doctest = false + +[dependencies] -- cgit 1.4.1-3-g733a5 From 1cff2e65570cbbf973bfe0c33edaaa914d385054 Mon Sep 17 00:00:00 2001 From: csmoe Date: Thu, 26 Sep 2019 03:09:51 +0800 Subject: move index_vec into rustc_index --- Cargo.lock | 8 + src/librustc_data_structures/Cargo.toml | 1 + src/librustc_data_structures/indexed_vec.rs | 830 ---------------------------- src/librustc_data_structures/lib.rs | 2 +- src/librustc_index/Cargo.toml | 1 + src/librustc_index/indexed_vec.rs | 830 ++++++++++++++++++++++++++++ src/librustc_index/lib.rs | 5 + 7 files changed, 846 insertions(+), 831 deletions(-) delete mode 100644 src/librustc_data_structures/indexed_vec.rs create mode 100644 src/librustc_index/indexed_vec.rs create mode 100644 src/librustc_index/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 5a92011d570..fd4b8f3e16c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3400,6 +3400,7 @@ dependencies = [ "rustc-hash", "rustc-rayon", "rustc-rayon-core", + "rustc_index", "serialize", "smallvec", "stable_deref_trait", @@ -3463,6 +3464,13 @@ dependencies = [ "syntax_pos", ] +[[package]] +name = "rustc_index" +version = "0.0.0" +dependencies = [ + "serialize", +] + [[package]] name = "rustc_interface" version = "0.0.0" diff --git a/src/librustc_data_structures/Cargo.toml b/src/librustc_data_structures/Cargo.toml index ae3403cf0ce..e020f2f8da9 100644 --- a/src/librustc_data_structures/Cargo.toml +++ b/src/librustc_data_structures/Cargo.toml @@ -24,6 +24,7 @@ rayon = { version = "0.2.0", package = "rustc-rayon" } rayon-core = { version = "0.2.0", package = "rustc-rayon-core" } rustc-hash = "1.0.1" smallvec = { version = "0.6.7", features = ["union", "may_dangle"] } +rustc_index = { path = "../librustc_index", package = "rustc_index" } [dependencies.parking_lot] version = "0.9" diff --git a/src/librustc_data_structures/indexed_vec.rs b/src/librustc_data_structures/indexed_vec.rs deleted file mode 100644 index 6e80b48a685..00000000000 --- a/src/librustc_data_structures/indexed_vec.rs +++ /dev/null @@ -1,830 +0,0 @@ -use rustc_serialize::{Encodable, Decodable, Encoder, Decoder}; - -use std::fmt::Debug; -use std::iter::{self, FromIterator}; -use std::slice; -use std::marker::PhantomData; -use std::ops::{Index, IndexMut, Range, RangeBounds}; -use std::fmt; -use std::hash::Hash; -use std::vec; -use std::u32; - -/// Represents some newtyped `usize` wrapper. -/// -/// Purpose: avoid mixing indexes for different bitvector domains. -pub trait Idx: Copy + 'static + Ord + Debug + Hash { - fn new(idx: usize) -> Self; - - fn index(self) -> usize; - - fn increment_by(&mut self, amount: usize) { - *self = self.plus(amount); - } - - fn plus(self, amount: usize) -> Self { - Self::new(self.index() + amount) - } -} - -impl Idx for usize { - #[inline] - fn new(idx: usize) -> Self { idx } - #[inline] - fn index(self) -> usize { self } -} - -impl Idx for u32 { - #[inline] - fn new(idx: usize) -> Self { assert!(idx <= u32::MAX as usize); idx as u32 } - #[inline] - fn index(self) -> usize { self as usize } -} - -/// Creates a struct type `S` that can be used as an index with -/// `IndexVec` and so on. -/// -/// There are two ways of interacting with these indices: -/// -/// - The `From` impls are the preferred way. So you can do -/// `S::from(v)` with a `usize` or `u32`. And you can convert back -/// to an integer with `u32::from(s)`. -/// -/// - Alternatively, you can use the methods `S::new(v)` and `s.index()` -/// to create/return a value. -/// -/// Internally, the index uses a u32, so the index must not exceed -/// `u32::MAX`. You can also customize things like the `Debug` impl, -/// what traits are derived, and so forth via the macro. -#[macro_export] -#[allow_internal_unstable(step_trait, rustc_attrs)] -macro_rules! newtype_index { - // ---- public rules ---- - - // Use default constants - ($(#[$attrs:meta])* $v:vis struct $name:ident { .. }) => ( - $crate::newtype_index!( - // Leave out derives marker so we can use its absence to ensure it comes first - @attrs [$(#[$attrs])*] - @type [$name] - // shave off 256 indices at the end to allow space for packing these indices into enums - @max [0xFFFF_FF00] - @vis [$v] - @debug_format ["{}"]); - ); - - // Define any constants - ($(#[$attrs:meta])* $v:vis struct $name:ident { $($tokens:tt)+ }) => ( - $crate::newtype_index!( - // Leave out derives marker so we can use its absence to ensure it comes first - @attrs [$(#[$attrs])*] - @type [$name] - // shave off 256 indices at the end to allow space for packing these indices into enums - @max [0xFFFF_FF00] - @vis [$v] - @debug_format ["{}"] - $($tokens)+); - ); - - // ---- private rules ---- - - // Base case, user-defined constants (if any) have already been defined - (@derives [$($derives:ident,)*] - @attrs [$(#[$attrs:meta])*] - @type [$type:ident] - @max [$max:expr] - @vis [$v:vis] - @debug_format [$debug_format:tt]) => ( - $(#[$attrs])* - #[derive(Copy, PartialEq, Eq, Hash, PartialOrd, Ord, $($derives),*)] - #[rustc_layout_scalar_valid_range_end($max)] - $v struct $type { - private: u32 - } - - impl Clone for $type { - fn clone(&self) -> Self { - *self - } - } - - impl $type { - $v const MAX_AS_U32: u32 = $max; - - $v const MAX: $type = $type::from_u32_const($max); - - #[inline] - $v fn from_usize(value: usize) -> Self { - assert!(value <= ($max as usize)); - unsafe { - $type::from_u32_unchecked(value as u32) - } - } - - #[inline] - $v fn from_u32(value: u32) -> Self { - assert!(value <= $max); - unsafe { - $type::from_u32_unchecked(value) - } - } - - /// Hacky variant of `from_u32` for use in constants. - /// This version checks the "max" constraint by using an - /// invalid array dereference. - #[inline] - $v const fn from_u32_const(value: u32) -> Self { - // This will fail at const eval time unless `value <= - // max` is true (in which case we get the index 0). - // It will also fail at runtime, of course, but in a - // kind of wacky way. - let _ = ["out of range value used"][ - !(value <= $max) as usize - ]; - - unsafe { - $type { private: value } - } - } - - #[inline] - $v const unsafe fn from_u32_unchecked(value: u32) -> Self { - $type { private: value } - } - - /// Extracts the value of this index as an integer. - #[inline] - $v fn index(self) -> usize { - self.as_usize() - } - - /// Extracts the value of this index as a `u32`. - #[inline] - $v fn as_u32(self) -> u32 { - self.private - } - - /// Extracts the value of this index as a `usize`. - #[inline] - $v fn as_usize(self) -> usize { - self.as_u32() as usize - } - } - - impl std::ops::Add for $type { - type Output = Self; - - fn add(self, other: usize) -> Self { - Self::new(self.index() + other) - } - } - - impl Idx for $type { - #[inline] - fn new(value: usize) -> Self { - Self::from(value) - } - - #[inline] - fn index(self) -> usize { - usize::from(self) - } - } - - impl ::std::iter::Step for $type { - #[inline] - fn steps_between(start: &Self, end: &Self) -> Option { - ::steps_between( - &Idx::index(*start), - &Idx::index(*end), - ) - } - - #[inline] - fn replace_one(&mut self) -> Self { - ::std::mem::replace(self, Self::new(1)) - } - - #[inline] - fn replace_zero(&mut self) -> Self { - ::std::mem::replace(self, Self::new(0)) - } - - #[inline] - fn add_one(&self) -> Self { - Self::new(Idx::index(*self) + 1) - } - - #[inline] - fn sub_one(&self) -> Self { - Self::new(Idx::index(*self) - 1) - } - - #[inline] - fn add_usize(&self, u: usize) -> Option { - Idx::index(*self).checked_add(u).map(Self::new) - } - - #[inline] - fn sub_usize(&self, u: usize) -> Option { - Idx::index(*self).checked_sub(u).map(Self::new) - } - } - - impl From<$type> for u32 { - #[inline] - fn from(v: $type) -> u32 { - v.as_u32() - } - } - - impl From<$type> for usize { - #[inline] - fn from(v: $type) -> usize { - v.as_usize() - } - } - - impl From for $type { - #[inline] - fn from(value: usize) -> Self { - $type::from_usize(value) - } - } - - impl From for $type { - #[inline] - fn from(value: u32) -> Self { - $type::from_u32(value) - } - } - - $crate::newtype_index!( - @handle_debug - @derives [$($derives,)*] - @type [$type] - @debug_format [$debug_format]); - ); - - // base case for handle_debug where format is custom. No Debug implementation is emitted. - (@handle_debug - @derives [$($_derives:ident,)*] - @type [$type:ident] - @debug_format [custom]) => (); - - // base case for handle_debug, no debug overrides found, so use default - (@handle_debug - @derives [] - @type [$type:ident] - @debug_format [$debug_format:tt]) => ( - impl ::std::fmt::Debug for $type { - fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - write!(fmt, $debug_format, self.as_u32()) - } - } - ); - - // Debug is requested for derive, don't generate any Debug implementation. - (@handle_debug - @derives [Debug, $($derives:ident,)*] - @type [$type:ident] - @debug_format [$debug_format:tt]) => (); - - // It's not Debug, so just pop it off the front of the derives stack and check the rest. - (@handle_debug - @derives [$_derive:ident, $($derives:ident,)*] - @type [$type:ident] - @debug_format [$debug_format:tt]) => ( - $crate::newtype_index!( - @handle_debug - @derives [$($derives,)*] - @type [$type] - @debug_format [$debug_format]); - ); - - // Append comma to end of derives list if it's missing - (@attrs [$(#[$attrs:meta])*] - @type [$type:ident] - @max [$max:expr] - @vis [$v:vis] - @debug_format [$debug_format:tt] - derive [$($derives:ident),*] - $($tokens:tt)*) => ( - $crate::newtype_index!( - @attrs [$(#[$attrs])*] - @type [$type] - @max [$max] - @vis [$v] - @debug_format [$debug_format] - derive [$($derives,)*] - $($tokens)*); - ); - - // By not including the @derives marker in this list nor in the default args, we can force it - // to come first if it exists. When encodable is custom, just use the derives list as-is. - (@attrs [$(#[$attrs:meta])*] - @type [$type:ident] - @max [$max:expr] - @vis [$v:vis] - @debug_format [$debug_format:tt] - derive [$($derives:ident,)+] - ENCODABLE = custom - $($tokens:tt)*) => ( - $crate::newtype_index!( - @attrs [$(#[$attrs])*] - @derives [$($derives,)+] - @type [$type] - @max [$max] - @vis [$v] - @debug_format [$debug_format] - $($tokens)*); - ); - - // By not including the @derives marker in this list nor in the default args, we can force it - // to come first if it exists. When encodable isn't custom, add serialization traits by default. - (@attrs [$(#[$attrs:meta])*] - @type [$type:ident] - @max [$max:expr] - @vis [$v:vis] - @debug_format [$debug_format:tt] - derive [$($derives:ident,)+] - $($tokens:tt)*) => ( - $crate::newtype_index!( - @derives [$($derives,)+ RustcEncodable,] - @attrs [$(#[$attrs])*] - @type [$type] - @max [$max] - @vis [$v] - @debug_format [$debug_format] - $($tokens)*); - $crate::newtype_index!(@decodable $type); - ); - - // The case where no derives are added, but encodable is overridden. Don't - // derive serialization traits - (@attrs [$(#[$attrs:meta])*] - @type [$type:ident] - @max [$max:expr] - @vis [$v:vis] - @debug_format [$debug_format:tt] - ENCODABLE = custom - $($tokens:tt)*) => ( - $crate::newtype_index!( - @derives [] - @attrs [$(#[$attrs])*] - @type [$type] - @max [$max] - @vis [$v] - @debug_format [$debug_format] - $($tokens)*); - ); - - // The case where no derives are added, add serialization derives by default - (@attrs [$(#[$attrs:meta])*] - @type [$type:ident] - @max [$max:expr] - @vis [$v:vis] - @debug_format [$debug_format:tt] - $($tokens:tt)*) => ( - $crate::newtype_index!( - @derives [RustcEncodable,] - @attrs [$(#[$attrs])*] - @type [$type] - @max [$max] - @vis [$v] - @debug_format [$debug_format] - $($tokens)*); - $crate::newtype_index!(@decodable $type); - ); - - (@decodable $type:ident) => ( - impl ::rustc_serialize::Decodable for $type { - fn decode(d: &mut D) -> Result { - d.read_u32().map(Self::from) - } - } - ); - - // Rewrite final without comma to one that includes comma - (@derives [$($derives:ident,)*] - @attrs [$(#[$attrs:meta])*] - @type [$type:ident] - @max [$max:expr] - @vis [$v:vis] - @debug_format [$debug_format:tt] - $name:ident = $constant:expr) => ( - $crate::newtype_index!( - @derives [$($derives,)*] - @attrs [$(#[$attrs])*] - @type [$type] - @max [$max] - @vis [$v] - @debug_format [$debug_format] - $name = $constant,); - ); - - // Rewrite final const without comma to one that includes comma - (@derives [$($derives:ident,)*] - @attrs [$(#[$attrs:meta])*] - @type [$type:ident] - @max [$max:expr] - @vis [$v:vis] - @debug_format [$debug_format:tt] - $(#[doc = $doc:expr])* - const $name:ident = $constant:expr) => ( - $crate::newtype_index!( - @derives [$($derives,)*] - @attrs [$(#[$attrs])*] - @type [$type] - @max [$max] - @vis [$v] - @debug_format [$debug_format] - $(#[doc = $doc])* const $name = $constant,); - ); - - // Replace existing default for max - (@derives [$($derives:ident,)*] - @attrs [$(#[$attrs:meta])*] - @type [$type:ident] - @max [$_max:expr] - @vis [$v:vis] - @debug_format [$debug_format:tt] - MAX = $max:expr, - $($tokens:tt)*) => ( - $crate::newtype_index!( - @derives [$($derives,)*] - @attrs [$(#[$attrs])*] - @type [$type] - @max [$max] - @vis [$v] - @debug_format [$debug_format] - $($tokens)*); - ); - - // Replace existing default for debug_format - (@derives [$($derives:ident,)*] - @attrs [$(#[$attrs:meta])*] - @type [$type:ident] - @max [$max:expr] - @vis [$v:vis] - @debug_format [$_debug_format:tt] - DEBUG_FORMAT = $debug_format:tt, - $($tokens:tt)*) => ( - $crate::newtype_index!( - @derives [$($derives,)*] - @attrs [$(#[$attrs])*] - @type [$type] - @max [$max] - @vis [$v] - @debug_format [$debug_format] - $($tokens)*); - ); - - // Assign a user-defined constant - (@derives [$($derives:ident,)*] - @attrs [$(#[$attrs:meta])*] - @type [$type:ident] - @max [$max:expr] - @vis [$v:vis] - @debug_format [$debug_format:tt] - $(#[doc = $doc:expr])* - const $name:ident = $constant:expr, - $($tokens:tt)*) => ( - $(#[doc = $doc])* - pub const $name: $type = $type::from_u32_const($constant); - $crate::newtype_index!( - @derives [$($derives,)*] - @attrs [$(#[$attrs])*] - @type [$type] - @max [$max] - @vis [$v] - @debug_format [$debug_format] - $($tokens)*); - ); -} - -#[derive(Clone, PartialEq, Eq, Hash)] -pub struct IndexVec { - pub raw: Vec, - _marker: PhantomData -} - -// Whether `IndexVec` is `Send` depends only on the data, -// not the phantom data. -unsafe impl Send for IndexVec where T: Send {} - -impl Encodable for IndexVec { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - Encodable::encode(&self.raw, s) - } -} - -impl Decodable for IndexVec { - fn decode(d: &mut D) -> Result { - Decodable::decode(d).map(|v| { - IndexVec { raw: v, _marker: PhantomData } - }) - } -} - -impl fmt::Debug for IndexVec { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Debug::fmt(&self.raw, fmt) - } -} - -pub type Enumerated = iter::Map, IntoIdx>; - -impl IndexVec { - #[inline] - pub fn new() -> Self { - IndexVec { raw: Vec::new(), _marker: PhantomData } - } - - #[inline] - pub fn from_raw(raw: Vec) -> Self { - IndexVec { raw, _marker: PhantomData } - } - - #[inline] - pub fn with_capacity(capacity: usize) -> Self { - IndexVec { raw: Vec::with_capacity(capacity), _marker: PhantomData } - } - - #[inline] - pub fn from_elem(elem: T, universe: &IndexVec) -> Self - where T: Clone - { - IndexVec { raw: vec![elem; universe.len()], _marker: PhantomData } - } - - #[inline] - pub fn from_elem_n(elem: T, n: usize) -> Self - where T: Clone - { - IndexVec { raw: vec![elem; n], _marker: PhantomData } - } - - #[inline] - pub fn push(&mut self, d: T) -> I { - let idx = I::new(self.len()); - self.raw.push(d); - idx - } - - #[inline] - pub fn pop(&mut self) -> Option { - self.raw.pop() - } - - #[inline] - pub fn len(&self) -> usize { - self.raw.len() - } - - /// Gives the next index that will be assigned when `push` is - /// called. - #[inline] - pub fn next_index(&self) -> I { - I::new(self.len()) - } - - #[inline] - pub fn is_empty(&self) -> bool { - self.raw.is_empty() - } - - #[inline] - pub fn into_iter(self) -> vec::IntoIter { - self.raw.into_iter() - } - - #[inline] - pub fn into_iter_enumerated(self) -> Enumerated> - { - self.raw.into_iter().enumerate().map(IntoIdx { _marker: PhantomData }) - } - - #[inline] - pub fn iter(&self) -> slice::Iter<'_, T> { - self.raw.iter() - } - - #[inline] - pub fn iter_enumerated(&self) -> Enumerated> - { - self.raw.iter().enumerate().map(IntoIdx { _marker: PhantomData }) - } - - #[inline] - pub fn indices(&self) -> iter::Map, IntoIdx> { - (0..self.len()).map(IntoIdx { _marker: PhantomData }) - } - - #[inline] - pub fn iter_mut(&mut self) -> slice::IterMut<'_, T> { - self.raw.iter_mut() - } - - #[inline] - pub fn iter_enumerated_mut(&mut self) -> Enumerated> - { - self.raw.iter_mut().enumerate().map(IntoIdx { _marker: PhantomData }) - } - - #[inline] - pub fn drain<'a, R: RangeBounds>( - &'a mut self, range: R) -> impl Iterator + 'a { - self.raw.drain(range) - } - - #[inline] - pub fn drain_enumerated<'a, R: RangeBounds>( - &'a mut self, range: R) -> impl Iterator + 'a { - self.raw.drain(range).enumerate().map(IntoIdx { _marker: PhantomData }) - } - - #[inline] - pub fn last(&self) -> Option { - self.len().checked_sub(1).map(I::new) - } - - #[inline] - pub fn shrink_to_fit(&mut self) { - self.raw.shrink_to_fit() - } - - #[inline] - pub fn swap(&mut self, a: I, b: I) { - self.raw.swap(a.index(), b.index()) - } - - #[inline] - pub fn truncate(&mut self, a: usize) { - self.raw.truncate(a) - } - - #[inline] - pub fn get(&self, index: I) -> Option<&T> { - self.raw.get(index.index()) - } - - #[inline] - pub fn get_mut(&mut self, index: I) -> Option<&mut T> { - self.raw.get_mut(index.index()) - } - - /// Returns mutable references to two distinct elements, a and b. Panics if a == b. - #[inline] - pub fn pick2_mut(&mut self, a: I, b: I) -> (&mut T, &mut T) { - let (ai, bi) = (a.index(), b.index()); - assert!(ai != bi); - - if ai < bi { - let (c1, c2) = self.raw.split_at_mut(bi); - (&mut c1[ai], &mut c2[0]) - } else { - let (c2, c1) = self.pick2_mut(b, a); - (c1, c2) - } - } - - pub fn convert_index_type(self) -> IndexVec { - IndexVec { - raw: self.raw, - _marker: PhantomData, - } - } -} - -impl IndexVec { - /// Grows the index vector so that it contains an entry for - /// `elem`; if that is already true, then has no - /// effect. Otherwise, inserts new values as needed by invoking - /// `fill_value`. - #[inline] - pub fn ensure_contains_elem(&mut self, elem: I, fill_value: impl FnMut() -> T) { - let min_new_len = elem.index() + 1; - if self.len() < min_new_len { - self.raw.resize_with(min_new_len, fill_value); - } - } - - #[inline] - pub fn resize(&mut self, new_len: usize, value: T) { - self.raw.resize(new_len, value) - } - - #[inline] - pub fn resize_to_elem(&mut self, elem: I, fill_value: impl FnMut() -> T) { - let min_new_len = elem.index() + 1; - self.raw.resize_with(min_new_len, fill_value); - } -} - -impl IndexVec { - #[inline] - pub fn binary_search(&self, value: &T) -> Result { - match self.raw.binary_search(value) { - Ok(i) => Ok(Idx::new(i)), - Err(i) => Err(Idx::new(i)), - } - } -} - -impl Index for IndexVec { - type Output = T; - - #[inline] - fn index(&self, index: I) -> &T { - &self.raw[index.index()] - } -} - -impl IndexMut for IndexVec { - #[inline] - fn index_mut(&mut self, index: I) -> &mut T { - &mut self.raw[index.index()] - } -} - -impl Default for IndexVec { - #[inline] - fn default() -> Self { - Self::new() - } -} - -impl Extend for IndexVec { - #[inline] - fn extend>(&mut self, iter: J) { - self.raw.extend(iter); - } -} - -impl FromIterator for IndexVec { - #[inline] - fn from_iter(iter: J) -> Self where J: IntoIterator { - IndexVec { raw: FromIterator::from_iter(iter), _marker: PhantomData } - } -} - -impl IntoIterator for IndexVec { - type Item = T; - type IntoIter = vec::IntoIter; - - #[inline] - fn into_iter(self) -> vec::IntoIter { - self.raw.into_iter() - } - -} - -impl<'a, I: Idx, T> IntoIterator for &'a IndexVec { - type Item = &'a T; - type IntoIter = slice::Iter<'a, T>; - - #[inline] - fn into_iter(self) -> slice::Iter<'a, T> { - self.raw.iter() - } -} - -impl<'a, I: Idx, T> IntoIterator for &'a mut IndexVec { - type Item = &'a mut T; - type IntoIter = slice::IterMut<'a, T>; - - #[inline] - fn into_iter(self) -> slice::IterMut<'a, T> { - self.raw.iter_mut() - } -} - -pub struct IntoIdx { _marker: PhantomData } -impl FnOnce<((usize, T),)> for IntoIdx { - type Output = (I, T); - - extern "rust-call" fn call_once(self, ((n, t),): ((usize, T),)) -> Self::Output { - (I::new(n), t) - } -} - -impl FnMut<((usize, T),)> for IntoIdx { - extern "rust-call" fn call_mut(&mut self, ((n, t),): ((usize, T),)) -> Self::Output { - (I::new(n), t) - } -} - -impl FnOnce<(usize,)> for IntoIdx { - type Output = I; - - extern "rust-call" fn call_once(self, (n,): (usize,)) -> Self::Output { - I::new(n) - } -} - -impl FnMut<(usize,)> for IntoIdx { - extern "rust-call" fn call_mut(&mut self, (n,): (usize,)) -> Self::Output { - I::new(n) - } -} diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index d6e9c479c9b..a9ef297fa99 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -37,6 +37,7 @@ extern crate libc; extern crate cfg_if; pub use rustc_serialize::hex::ToHex; +pub use rustc_index::{indexed_vec, newtype_index}; #[inline(never)] #[cold] @@ -75,7 +76,6 @@ pub mod flock; pub mod fx; pub mod stable_map; pub mod graph; -pub mod indexed_vec; pub mod jobserver; pub mod obligation_forest; pub mod owning_ref; diff --git a/src/librustc_index/Cargo.toml b/src/librustc_index/Cargo.toml index f3d837c73b8..10e66ffe590 100644 --- a/src/librustc_index/Cargo.toml +++ b/src/librustc_index/Cargo.toml @@ -10,3 +10,4 @@ path = "lib.rs" doctest = false [dependencies] +rustc_serialize = { path = "../libserialize", package = "serialize" } diff --git a/src/librustc_index/indexed_vec.rs b/src/librustc_index/indexed_vec.rs new file mode 100644 index 00000000000..6e80b48a685 --- /dev/null +++ b/src/librustc_index/indexed_vec.rs @@ -0,0 +1,830 @@ +use rustc_serialize::{Encodable, Decodable, Encoder, Decoder}; + +use std::fmt::Debug; +use std::iter::{self, FromIterator}; +use std::slice; +use std::marker::PhantomData; +use std::ops::{Index, IndexMut, Range, RangeBounds}; +use std::fmt; +use std::hash::Hash; +use std::vec; +use std::u32; + +/// Represents some newtyped `usize` wrapper. +/// +/// Purpose: avoid mixing indexes for different bitvector domains. +pub trait Idx: Copy + 'static + Ord + Debug + Hash { + fn new(idx: usize) -> Self; + + fn index(self) -> usize; + + fn increment_by(&mut self, amount: usize) { + *self = self.plus(amount); + } + + fn plus(self, amount: usize) -> Self { + Self::new(self.index() + amount) + } +} + +impl Idx for usize { + #[inline] + fn new(idx: usize) -> Self { idx } + #[inline] + fn index(self) -> usize { self } +} + +impl Idx for u32 { + #[inline] + fn new(idx: usize) -> Self { assert!(idx <= u32::MAX as usize); idx as u32 } + #[inline] + fn index(self) -> usize { self as usize } +} + +/// Creates a struct type `S` that can be used as an index with +/// `IndexVec` and so on. +/// +/// There are two ways of interacting with these indices: +/// +/// - The `From` impls are the preferred way. So you can do +/// `S::from(v)` with a `usize` or `u32`. And you can convert back +/// to an integer with `u32::from(s)`. +/// +/// - Alternatively, you can use the methods `S::new(v)` and `s.index()` +/// to create/return a value. +/// +/// Internally, the index uses a u32, so the index must not exceed +/// `u32::MAX`. You can also customize things like the `Debug` impl, +/// what traits are derived, and so forth via the macro. +#[macro_export] +#[allow_internal_unstable(step_trait, rustc_attrs)] +macro_rules! newtype_index { + // ---- public rules ---- + + // Use default constants + ($(#[$attrs:meta])* $v:vis struct $name:ident { .. }) => ( + $crate::newtype_index!( + // Leave out derives marker so we can use its absence to ensure it comes first + @attrs [$(#[$attrs])*] + @type [$name] + // shave off 256 indices at the end to allow space for packing these indices into enums + @max [0xFFFF_FF00] + @vis [$v] + @debug_format ["{}"]); + ); + + // Define any constants + ($(#[$attrs:meta])* $v:vis struct $name:ident { $($tokens:tt)+ }) => ( + $crate::newtype_index!( + // Leave out derives marker so we can use its absence to ensure it comes first + @attrs [$(#[$attrs])*] + @type [$name] + // shave off 256 indices at the end to allow space for packing these indices into enums + @max [0xFFFF_FF00] + @vis [$v] + @debug_format ["{}"] + $($tokens)+); + ); + + // ---- private rules ---- + + // Base case, user-defined constants (if any) have already been defined + (@derives [$($derives:ident,)*] + @attrs [$(#[$attrs:meta])*] + @type [$type:ident] + @max [$max:expr] + @vis [$v:vis] + @debug_format [$debug_format:tt]) => ( + $(#[$attrs])* + #[derive(Copy, PartialEq, Eq, Hash, PartialOrd, Ord, $($derives),*)] + #[rustc_layout_scalar_valid_range_end($max)] + $v struct $type { + private: u32 + } + + impl Clone for $type { + fn clone(&self) -> Self { + *self + } + } + + impl $type { + $v const MAX_AS_U32: u32 = $max; + + $v const MAX: $type = $type::from_u32_const($max); + + #[inline] + $v fn from_usize(value: usize) -> Self { + assert!(value <= ($max as usize)); + unsafe { + $type::from_u32_unchecked(value as u32) + } + } + + #[inline] + $v fn from_u32(value: u32) -> Self { + assert!(value <= $max); + unsafe { + $type::from_u32_unchecked(value) + } + } + + /// Hacky variant of `from_u32` for use in constants. + /// This version checks the "max" constraint by using an + /// invalid array dereference. + #[inline] + $v const fn from_u32_const(value: u32) -> Self { + // This will fail at const eval time unless `value <= + // max` is true (in which case we get the index 0). + // It will also fail at runtime, of course, but in a + // kind of wacky way. + let _ = ["out of range value used"][ + !(value <= $max) as usize + ]; + + unsafe { + $type { private: value } + } + } + + #[inline] + $v const unsafe fn from_u32_unchecked(value: u32) -> Self { + $type { private: value } + } + + /// Extracts the value of this index as an integer. + #[inline] + $v fn index(self) -> usize { + self.as_usize() + } + + /// Extracts the value of this index as a `u32`. + #[inline] + $v fn as_u32(self) -> u32 { + self.private + } + + /// Extracts the value of this index as a `usize`. + #[inline] + $v fn as_usize(self) -> usize { + self.as_u32() as usize + } + } + + impl std::ops::Add for $type { + type Output = Self; + + fn add(self, other: usize) -> Self { + Self::new(self.index() + other) + } + } + + impl Idx for $type { + #[inline] + fn new(value: usize) -> Self { + Self::from(value) + } + + #[inline] + fn index(self) -> usize { + usize::from(self) + } + } + + impl ::std::iter::Step for $type { + #[inline] + fn steps_between(start: &Self, end: &Self) -> Option { + ::steps_between( + &Idx::index(*start), + &Idx::index(*end), + ) + } + + #[inline] + fn replace_one(&mut self) -> Self { + ::std::mem::replace(self, Self::new(1)) + } + + #[inline] + fn replace_zero(&mut self) -> Self { + ::std::mem::replace(self, Self::new(0)) + } + + #[inline] + fn add_one(&self) -> Self { + Self::new(Idx::index(*self) + 1) + } + + #[inline] + fn sub_one(&self) -> Self { + Self::new(Idx::index(*self) - 1) + } + + #[inline] + fn add_usize(&self, u: usize) -> Option { + Idx::index(*self).checked_add(u).map(Self::new) + } + + #[inline] + fn sub_usize(&self, u: usize) -> Option { + Idx::index(*self).checked_sub(u).map(Self::new) + } + } + + impl From<$type> for u32 { + #[inline] + fn from(v: $type) -> u32 { + v.as_u32() + } + } + + impl From<$type> for usize { + #[inline] + fn from(v: $type) -> usize { + v.as_usize() + } + } + + impl From for $type { + #[inline] + fn from(value: usize) -> Self { + $type::from_usize(value) + } + } + + impl From for $type { + #[inline] + fn from(value: u32) -> Self { + $type::from_u32(value) + } + } + + $crate::newtype_index!( + @handle_debug + @derives [$($derives,)*] + @type [$type] + @debug_format [$debug_format]); + ); + + // base case for handle_debug where format is custom. No Debug implementation is emitted. + (@handle_debug + @derives [$($_derives:ident,)*] + @type [$type:ident] + @debug_format [custom]) => (); + + // base case for handle_debug, no debug overrides found, so use default + (@handle_debug + @derives [] + @type [$type:ident] + @debug_format [$debug_format:tt]) => ( + impl ::std::fmt::Debug for $type { + fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + write!(fmt, $debug_format, self.as_u32()) + } + } + ); + + // Debug is requested for derive, don't generate any Debug implementation. + (@handle_debug + @derives [Debug, $($derives:ident,)*] + @type [$type:ident] + @debug_format [$debug_format:tt]) => (); + + // It's not Debug, so just pop it off the front of the derives stack and check the rest. + (@handle_debug + @derives [$_derive:ident, $($derives:ident,)*] + @type [$type:ident] + @debug_format [$debug_format:tt]) => ( + $crate::newtype_index!( + @handle_debug + @derives [$($derives,)*] + @type [$type] + @debug_format [$debug_format]); + ); + + // Append comma to end of derives list if it's missing + (@attrs [$(#[$attrs:meta])*] + @type [$type:ident] + @max [$max:expr] + @vis [$v:vis] + @debug_format [$debug_format:tt] + derive [$($derives:ident),*] + $($tokens:tt)*) => ( + $crate::newtype_index!( + @attrs [$(#[$attrs])*] + @type [$type] + @max [$max] + @vis [$v] + @debug_format [$debug_format] + derive [$($derives,)*] + $($tokens)*); + ); + + // By not including the @derives marker in this list nor in the default args, we can force it + // to come first if it exists. When encodable is custom, just use the derives list as-is. + (@attrs [$(#[$attrs:meta])*] + @type [$type:ident] + @max [$max:expr] + @vis [$v:vis] + @debug_format [$debug_format:tt] + derive [$($derives:ident,)+] + ENCODABLE = custom + $($tokens:tt)*) => ( + $crate::newtype_index!( + @attrs [$(#[$attrs])*] + @derives [$($derives,)+] + @type [$type] + @max [$max] + @vis [$v] + @debug_format [$debug_format] + $($tokens)*); + ); + + // By not including the @derives marker in this list nor in the default args, we can force it + // to come first if it exists. When encodable isn't custom, add serialization traits by default. + (@attrs [$(#[$attrs:meta])*] + @type [$type:ident] + @max [$max:expr] + @vis [$v:vis] + @debug_format [$debug_format:tt] + derive [$($derives:ident,)+] + $($tokens:tt)*) => ( + $crate::newtype_index!( + @derives [$($derives,)+ RustcEncodable,] + @attrs [$(#[$attrs])*] + @type [$type] + @max [$max] + @vis [$v] + @debug_format [$debug_format] + $($tokens)*); + $crate::newtype_index!(@decodable $type); + ); + + // The case where no derives are added, but encodable is overridden. Don't + // derive serialization traits + (@attrs [$(#[$attrs:meta])*] + @type [$type:ident] + @max [$max:expr] + @vis [$v:vis] + @debug_format [$debug_format:tt] + ENCODABLE = custom + $($tokens:tt)*) => ( + $crate::newtype_index!( + @derives [] + @attrs [$(#[$attrs])*] + @type [$type] + @max [$max] + @vis [$v] + @debug_format [$debug_format] + $($tokens)*); + ); + + // The case where no derives are added, add serialization derives by default + (@attrs [$(#[$attrs:meta])*] + @type [$type:ident] + @max [$max:expr] + @vis [$v:vis] + @debug_format [$debug_format:tt] + $($tokens:tt)*) => ( + $crate::newtype_index!( + @derives [RustcEncodable,] + @attrs [$(#[$attrs])*] + @type [$type] + @max [$max] + @vis [$v] + @debug_format [$debug_format] + $($tokens)*); + $crate::newtype_index!(@decodable $type); + ); + + (@decodable $type:ident) => ( + impl ::rustc_serialize::Decodable for $type { + fn decode(d: &mut D) -> Result { + d.read_u32().map(Self::from) + } + } + ); + + // Rewrite final without comma to one that includes comma + (@derives [$($derives:ident,)*] + @attrs [$(#[$attrs:meta])*] + @type [$type:ident] + @max [$max:expr] + @vis [$v:vis] + @debug_format [$debug_format:tt] + $name:ident = $constant:expr) => ( + $crate::newtype_index!( + @derives [$($derives,)*] + @attrs [$(#[$attrs])*] + @type [$type] + @max [$max] + @vis [$v] + @debug_format [$debug_format] + $name = $constant,); + ); + + // Rewrite final const without comma to one that includes comma + (@derives [$($derives:ident,)*] + @attrs [$(#[$attrs:meta])*] + @type [$type:ident] + @max [$max:expr] + @vis [$v:vis] + @debug_format [$debug_format:tt] + $(#[doc = $doc:expr])* + const $name:ident = $constant:expr) => ( + $crate::newtype_index!( + @derives [$($derives,)*] + @attrs [$(#[$attrs])*] + @type [$type] + @max [$max] + @vis [$v] + @debug_format [$debug_format] + $(#[doc = $doc])* const $name = $constant,); + ); + + // Replace existing default for max + (@derives [$($derives:ident,)*] + @attrs [$(#[$attrs:meta])*] + @type [$type:ident] + @max [$_max:expr] + @vis [$v:vis] + @debug_format [$debug_format:tt] + MAX = $max:expr, + $($tokens:tt)*) => ( + $crate::newtype_index!( + @derives [$($derives,)*] + @attrs [$(#[$attrs])*] + @type [$type] + @max [$max] + @vis [$v] + @debug_format [$debug_format] + $($tokens)*); + ); + + // Replace existing default for debug_format + (@derives [$($derives:ident,)*] + @attrs [$(#[$attrs:meta])*] + @type [$type:ident] + @max [$max:expr] + @vis [$v:vis] + @debug_format [$_debug_format:tt] + DEBUG_FORMAT = $debug_format:tt, + $($tokens:tt)*) => ( + $crate::newtype_index!( + @derives [$($derives,)*] + @attrs [$(#[$attrs])*] + @type [$type] + @max [$max] + @vis [$v] + @debug_format [$debug_format] + $($tokens)*); + ); + + // Assign a user-defined constant + (@derives [$($derives:ident,)*] + @attrs [$(#[$attrs:meta])*] + @type [$type:ident] + @max [$max:expr] + @vis [$v:vis] + @debug_format [$debug_format:tt] + $(#[doc = $doc:expr])* + const $name:ident = $constant:expr, + $($tokens:tt)*) => ( + $(#[doc = $doc])* + pub const $name: $type = $type::from_u32_const($constant); + $crate::newtype_index!( + @derives [$($derives,)*] + @attrs [$(#[$attrs])*] + @type [$type] + @max [$max] + @vis [$v] + @debug_format [$debug_format] + $($tokens)*); + ); +} + +#[derive(Clone, PartialEq, Eq, Hash)] +pub struct IndexVec { + pub raw: Vec, + _marker: PhantomData +} + +// Whether `IndexVec` is `Send` depends only on the data, +// not the phantom data. +unsafe impl Send for IndexVec where T: Send {} + +impl Encodable for IndexVec { + fn encode(&self, s: &mut S) -> Result<(), S::Error> { + Encodable::encode(&self.raw, s) + } +} + +impl Decodable for IndexVec { + fn decode(d: &mut D) -> Result { + Decodable::decode(d).map(|v| { + IndexVec { raw: v, _marker: PhantomData } + }) + } +} + +impl fmt::Debug for IndexVec { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Debug::fmt(&self.raw, fmt) + } +} + +pub type Enumerated = iter::Map, IntoIdx>; + +impl IndexVec { + #[inline] + pub fn new() -> Self { + IndexVec { raw: Vec::new(), _marker: PhantomData } + } + + #[inline] + pub fn from_raw(raw: Vec) -> Self { + IndexVec { raw, _marker: PhantomData } + } + + #[inline] + pub fn with_capacity(capacity: usize) -> Self { + IndexVec { raw: Vec::with_capacity(capacity), _marker: PhantomData } + } + + #[inline] + pub fn from_elem(elem: T, universe: &IndexVec) -> Self + where T: Clone + { + IndexVec { raw: vec![elem; universe.len()], _marker: PhantomData } + } + + #[inline] + pub fn from_elem_n(elem: T, n: usize) -> Self + where T: Clone + { + IndexVec { raw: vec![elem; n], _marker: PhantomData } + } + + #[inline] + pub fn push(&mut self, d: T) -> I { + let idx = I::new(self.len()); + self.raw.push(d); + idx + } + + #[inline] + pub fn pop(&mut self) -> Option { + self.raw.pop() + } + + #[inline] + pub fn len(&self) -> usize { + self.raw.len() + } + + /// Gives the next index that will be assigned when `push` is + /// called. + #[inline] + pub fn next_index(&self) -> I { + I::new(self.len()) + } + + #[inline] + pub fn is_empty(&self) -> bool { + self.raw.is_empty() + } + + #[inline] + pub fn into_iter(self) -> vec::IntoIter { + self.raw.into_iter() + } + + #[inline] + pub fn into_iter_enumerated(self) -> Enumerated> + { + self.raw.into_iter().enumerate().map(IntoIdx { _marker: PhantomData }) + } + + #[inline] + pub fn iter(&self) -> slice::Iter<'_, T> { + self.raw.iter() + } + + #[inline] + pub fn iter_enumerated(&self) -> Enumerated> + { + self.raw.iter().enumerate().map(IntoIdx { _marker: PhantomData }) + } + + #[inline] + pub fn indices(&self) -> iter::Map, IntoIdx> { + (0..self.len()).map(IntoIdx { _marker: PhantomData }) + } + + #[inline] + pub fn iter_mut(&mut self) -> slice::IterMut<'_, T> { + self.raw.iter_mut() + } + + #[inline] + pub fn iter_enumerated_mut(&mut self) -> Enumerated> + { + self.raw.iter_mut().enumerate().map(IntoIdx { _marker: PhantomData }) + } + + #[inline] + pub fn drain<'a, R: RangeBounds>( + &'a mut self, range: R) -> impl Iterator + 'a { + self.raw.drain(range) + } + + #[inline] + pub fn drain_enumerated<'a, R: RangeBounds>( + &'a mut self, range: R) -> impl Iterator + 'a { + self.raw.drain(range).enumerate().map(IntoIdx { _marker: PhantomData }) + } + + #[inline] + pub fn last(&self) -> Option { + self.len().checked_sub(1).map(I::new) + } + + #[inline] + pub fn shrink_to_fit(&mut self) { + self.raw.shrink_to_fit() + } + + #[inline] + pub fn swap(&mut self, a: I, b: I) { + self.raw.swap(a.index(), b.index()) + } + + #[inline] + pub fn truncate(&mut self, a: usize) { + self.raw.truncate(a) + } + + #[inline] + pub fn get(&self, index: I) -> Option<&T> { + self.raw.get(index.index()) + } + + #[inline] + pub fn get_mut(&mut self, index: I) -> Option<&mut T> { + self.raw.get_mut(index.index()) + } + + /// Returns mutable references to two distinct elements, a and b. Panics if a == b. + #[inline] + pub fn pick2_mut(&mut self, a: I, b: I) -> (&mut T, &mut T) { + let (ai, bi) = (a.index(), b.index()); + assert!(ai != bi); + + if ai < bi { + let (c1, c2) = self.raw.split_at_mut(bi); + (&mut c1[ai], &mut c2[0]) + } else { + let (c2, c1) = self.pick2_mut(b, a); + (c1, c2) + } + } + + pub fn convert_index_type(self) -> IndexVec { + IndexVec { + raw: self.raw, + _marker: PhantomData, + } + } +} + +impl IndexVec { + /// Grows the index vector so that it contains an entry for + /// `elem`; if that is already true, then has no + /// effect. Otherwise, inserts new values as needed by invoking + /// `fill_value`. + #[inline] + pub fn ensure_contains_elem(&mut self, elem: I, fill_value: impl FnMut() -> T) { + let min_new_len = elem.index() + 1; + if self.len() < min_new_len { + self.raw.resize_with(min_new_len, fill_value); + } + } + + #[inline] + pub fn resize(&mut self, new_len: usize, value: T) { + self.raw.resize(new_len, value) + } + + #[inline] + pub fn resize_to_elem(&mut self, elem: I, fill_value: impl FnMut() -> T) { + let min_new_len = elem.index() + 1; + self.raw.resize_with(min_new_len, fill_value); + } +} + +impl IndexVec { + #[inline] + pub fn binary_search(&self, value: &T) -> Result { + match self.raw.binary_search(value) { + Ok(i) => Ok(Idx::new(i)), + Err(i) => Err(Idx::new(i)), + } + } +} + +impl Index for IndexVec { + type Output = T; + + #[inline] + fn index(&self, index: I) -> &T { + &self.raw[index.index()] + } +} + +impl IndexMut for IndexVec { + #[inline] + fn index_mut(&mut self, index: I) -> &mut T { + &mut self.raw[index.index()] + } +} + +impl Default for IndexVec { + #[inline] + fn default() -> Self { + Self::new() + } +} + +impl Extend for IndexVec { + #[inline] + fn extend>(&mut self, iter: J) { + self.raw.extend(iter); + } +} + +impl FromIterator for IndexVec { + #[inline] + fn from_iter(iter: J) -> Self where J: IntoIterator { + IndexVec { raw: FromIterator::from_iter(iter), _marker: PhantomData } + } +} + +impl IntoIterator for IndexVec { + type Item = T; + type IntoIter = vec::IntoIter; + + #[inline] + fn into_iter(self) -> vec::IntoIter { + self.raw.into_iter() + } + +} + +impl<'a, I: Idx, T> IntoIterator for &'a IndexVec { + type Item = &'a T; + type IntoIter = slice::Iter<'a, T>; + + #[inline] + fn into_iter(self) -> slice::Iter<'a, T> { + self.raw.iter() + } +} + +impl<'a, I: Idx, T> IntoIterator for &'a mut IndexVec { + type Item = &'a mut T; + type IntoIter = slice::IterMut<'a, T>; + + #[inline] + fn into_iter(self) -> slice::IterMut<'a, T> { + self.raw.iter_mut() + } +} + +pub struct IntoIdx { _marker: PhantomData } +impl FnOnce<((usize, T),)> for IntoIdx { + type Output = (I, T); + + extern "rust-call" fn call_once(self, ((n, t),): ((usize, T),)) -> Self::Output { + (I::new(n), t) + } +} + +impl FnMut<((usize, T),)> for IntoIdx { + extern "rust-call" fn call_mut(&mut self, ((n, t),): ((usize, T),)) -> Self::Output { + (I::new(n), t) + } +} + +impl FnOnce<(usize,)> for IntoIdx { + type Output = I; + + extern "rust-call" fn call_once(self, (n,): (usize,)) -> Self::Output { + I::new(n) + } +} + +impl FnMut<(usize,)> for IntoIdx { + extern "rust-call" fn call_mut(&mut self, (n,): (usize,)) -> Self::Output { + I::new(n) + } +} diff --git a/src/librustc_index/lib.rs b/src/librustc_index/lib.rs new file mode 100644 index 00000000000..c4c4948e7bf --- /dev/null +++ b/src/librustc_index/lib.rs @@ -0,0 +1,5 @@ +#![feature(allow_internal_unstable)] +#![feature(unboxed_closures)] +#![feature(fn_traits)] + +pub mod indexed_vec; -- cgit 1.4.1-3-g733a5 From 17990637b3e4e17fd5fcd3a94bf03963c38b5753 Mon Sep 17 00:00:00 2001 From: csmoe Date: Thu, 26 Sep 2019 03:26:16 +0000 Subject: move bit_set into rustc_index --- Cargo.lock | 1 + src/librustc_data_structures/bit_set.rs | 984 -------------------------- src/librustc_data_structures/bit_set/tests.rs | 369 ---------- src/librustc_data_structures/lib.rs | 3 +- src/librustc_index/Cargo.toml | 1 + src/librustc_index/bit_set.rs | 984 ++++++++++++++++++++++++++ src/librustc_index/bit_set/tests.rs | 369 ++++++++++ src/librustc_index/lib.rs | 1 + 8 files changed, 1357 insertions(+), 1355 deletions(-) delete mode 100644 src/librustc_data_structures/bit_set.rs delete mode 100644 src/librustc_data_structures/bit_set/tests.rs create mode 100644 src/librustc_index/bit_set.rs create mode 100644 src/librustc_index/bit_set/tests.rs diff --git a/Cargo.lock b/Cargo.lock index fd4b8f3e16c..59505ff7ed7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3469,6 +3469,7 @@ name = "rustc_index" version = "0.0.0" dependencies = [ "serialize", + "smallvec", ] [[package]] diff --git a/src/librustc_data_structures/bit_set.rs b/src/librustc_data_structures/bit_set.rs deleted file mode 100644 index fe8ef642430..00000000000 --- a/src/librustc_data_structures/bit_set.rs +++ /dev/null @@ -1,984 +0,0 @@ -use crate::indexed_vec::{Idx, IndexVec}; -use smallvec::SmallVec; -use std::fmt; -use std::iter; -use std::marker::PhantomData; -use std::mem; -use std::slice; - -#[cfg(test)] -mod tests; - -pub type Word = u64; -pub const WORD_BYTES: usize = mem::size_of::(); -pub const WORD_BITS: usize = WORD_BYTES * 8; - -/// A fixed-size bitset type with a dense representation. It does not support -/// resizing after creation; use `GrowableBitSet` for that. -/// -/// `T` is an index type, typically a newtyped `usize` wrapper, but it can also -/// just be `usize`. -/// -/// All operations that involve an element will panic if the element is equal -/// to or greater than the domain size. All operations that involve two bitsets -/// will panic if the bitsets have differing domain sizes. -#[derive(Clone, Eq, PartialEq, RustcDecodable, RustcEncodable)] -pub struct BitSet { - domain_size: usize, - words: Vec, - marker: PhantomData, -} - -impl BitSet { - /// Creates a new, empty bitset with a given `domain_size`. - #[inline] - pub fn new_empty(domain_size: usize) -> BitSet { - let num_words = num_words(domain_size); - BitSet { - domain_size, - words: vec![0; num_words], - marker: PhantomData, - } - } - - /// Creates a new, filled bitset with a given `domain_size`. - #[inline] - pub fn new_filled(domain_size: usize) -> BitSet { - let num_words = num_words(domain_size); - let mut result = BitSet { - domain_size, - words: vec![!0; num_words], - marker: PhantomData, - }; - result.clear_excess_bits(); - result - } - - /// Gets the domain size. - pub fn domain_size(&self) -> usize { - self.domain_size - } - - /// Clear all elements. - #[inline] - pub fn clear(&mut self) { - for word in &mut self.words { - *word = 0; - } - } - - /// Clear excess bits in the final word. - fn clear_excess_bits(&mut self) { - let num_bits_in_final_word = self.domain_size % WORD_BITS; - if num_bits_in_final_word > 0 { - let mask = (1 << num_bits_in_final_word) - 1; - let final_word_idx = self.words.len() - 1; - self.words[final_word_idx] &= mask; - } - } - - /// Efficiently overwrite `self` with `other`. - pub fn overwrite(&mut self, other: &BitSet) { - assert!(self.domain_size == other.domain_size); - self.words.clone_from_slice(&other.words); - } - - /// Count the number of set bits in the set. - pub fn count(&self) -> usize { - self.words.iter().map(|e| e.count_ones() as usize).sum() - } - - /// Returns `true` if `self` contains `elem`. - #[inline] - pub fn contains(&self, elem: T) -> bool { - assert!(elem.index() < self.domain_size); - let (word_index, mask) = word_index_and_mask(elem); - (self.words[word_index] & mask) != 0 - } - - /// Is `self` is a (non-strict) superset of `other`? - #[inline] - pub fn superset(&self, other: &BitSet) -> bool { - assert_eq!(self.domain_size, other.domain_size); - self.words.iter().zip(&other.words).all(|(a, b)| (a & b) == *b) - } - - /// Is the set empty? - #[inline] - pub fn is_empty(&self) -> bool { - self.words.iter().all(|a| *a == 0) - } - - /// Insert `elem`. Returns whether the set has changed. - #[inline] - pub fn insert(&mut self, elem: T) -> bool { - assert!(elem.index() < self.domain_size); - let (word_index, mask) = word_index_and_mask(elem); - let word_ref = &mut self.words[word_index]; - let word = *word_ref; - let new_word = word | mask; - *word_ref = new_word; - new_word != word - } - - /// Sets all bits to true. - pub fn insert_all(&mut self) { - for word in &mut self.words { - *word = !0; - } - self.clear_excess_bits(); - } - - /// Returns `true` if the set has changed. - #[inline] - pub fn remove(&mut self, elem: T) -> bool { - assert!(elem.index() < self.domain_size); - let (word_index, mask) = word_index_and_mask(elem); - let word_ref = &mut self.words[word_index]; - let word = *word_ref; - let new_word = word & !mask; - *word_ref = new_word; - new_word != word - } - - /// Sets `self = self | other` and returns `true` if `self` changed - /// (i.e., if new bits were added). - pub fn union(&mut self, other: &impl UnionIntoBitSet) -> bool { - other.union_into(self) - } - - /// Sets `self = self - other` and returns `true` if `self` changed. - /// (i.e., if any bits were removed). - pub fn subtract(&mut self, other: &impl SubtractFromBitSet) -> bool { - other.subtract_from(self) - } - - /// Sets `self = self & other` and return `true` if `self` changed. - /// (i.e., if any bits were removed). - pub fn intersect(&mut self, other: &BitSet) -> bool { - assert_eq!(self.domain_size, other.domain_size); - bitwise(&mut self.words, &other.words, |a, b| { a & b }) - } - - /// Gets a slice of the underlying words. - pub fn words(&self) -> &[Word] { - &self.words - } - - /// Iterates over the indices of set bits in a sorted order. - #[inline] - pub fn iter(&self) -> BitIter<'_, T> { - BitIter { - cur: None, - iter: self.words.iter().enumerate(), - marker: PhantomData, - } - } - - /// Duplicates the set as a hybrid set. - pub fn to_hybrid(&self) -> HybridBitSet { - // Note: we currently don't bother trying to make a Sparse set. - HybridBitSet::Dense(self.to_owned()) - } - - /// Set `self = self | other`. In contrast to `union` returns `true` if the set contains at - /// least one bit that is not in `other` (i.e. `other` is not a superset of `self`). - /// - /// This is an optimization for union of a hybrid bitset. - fn reverse_union_sparse(&mut self, sparse: &SparseBitSet) -> bool { - assert!(sparse.domain_size == self.domain_size); - self.clear_excess_bits(); - - let mut not_already = false; - // Index of the current word not yet merged. - let mut current_index = 0; - // Mask of bits that came from the sparse set in the current word. - let mut new_bit_mask = 0; - for (word_index, mask) in sparse.iter().map(|x| word_index_and_mask(*x)) { - // Next bit is in a word not inspected yet. - if word_index > current_index { - self.words[current_index] |= new_bit_mask; - // Were there any bits in the old word that did not occur in the sparse set? - not_already |= (self.words[current_index] ^ new_bit_mask) != 0; - // Check all words we skipped for any set bit. - not_already |= self.words[current_index+1..word_index].iter().any(|&x| x != 0); - // Update next word. - current_index = word_index; - // Reset bit mask, no bits have been merged yet. - new_bit_mask = 0; - } - // Add bit and mark it as coming from the sparse set. - // self.words[word_index] |= mask; - new_bit_mask |= mask; - } - self.words[current_index] |= new_bit_mask; - // Any bits in the last inspected word that were not in the sparse set? - not_already |= (self.words[current_index] ^ new_bit_mask) != 0; - // Any bits in the tail? Note `clear_excess_bits` before. - not_already |= self.words[current_index+1..].iter().any(|&x| x != 0); - - not_already - } -} - -/// This is implemented by all the bitsets so that BitSet::union() can be -/// passed any type of bitset. -pub trait UnionIntoBitSet { - // Performs `other = other | self`. - fn union_into(&self, other: &mut BitSet) -> bool; -} - -/// This is implemented by all the bitsets so that BitSet::subtract() can be -/// passed any type of bitset. -pub trait SubtractFromBitSet { - // Performs `other = other - self`. - fn subtract_from(&self, other: &mut BitSet) -> bool; -} - -impl UnionIntoBitSet for BitSet { - fn union_into(&self, other: &mut BitSet) -> bool { - assert_eq!(self.domain_size, other.domain_size); - bitwise(&mut other.words, &self.words, |a, b| { a | b }) - } -} - -impl SubtractFromBitSet for BitSet { - fn subtract_from(&self, other: &mut BitSet) -> bool { - assert_eq!(self.domain_size, other.domain_size); - bitwise(&mut other.words, &self.words, |a, b| { a & !b }) - } -} - -impl fmt::Debug for BitSet { - fn fmt(&self, w: &mut fmt::Formatter<'_>) -> fmt::Result { - w.debug_list() - .entries(self.iter()) - .finish() - } -} - -impl ToString for BitSet { - fn to_string(&self) -> String { - let mut result = String::new(); - let mut sep = '['; - - // Note: this is a little endian printout of bytes. - - // i tracks how many bits we have printed so far. - let mut i = 0; - for word in &self.words { - let mut word = *word; - for _ in 0..WORD_BYTES { // for each byte in `word`: - let remain = self.domain_size - i; - // If less than a byte remains, then mask just that many bits. - let mask = if remain <= 8 { (1 << remain) - 1 } else { 0xFF }; - assert!(mask <= 0xFF); - let byte = word & mask; - - result.push_str(&format!("{}{:02x}", sep, byte)); - - if remain <= 8 { break; } - word >>= 8; - i += 8; - sep = '-'; - } - sep = '|'; - } - result.push(']'); - - result - } -} - -pub struct BitIter<'a, T: Idx> { - cur: Option<(Word, usize)>, - iter: iter::Enumerate>, - marker: PhantomData -} - -impl<'a, T: Idx> Iterator for BitIter<'a, T> { - type Item = T; - fn next(&mut self) -> Option { - loop { - if let Some((ref mut word, offset)) = self.cur { - let bit_pos = word.trailing_zeros() as usize; - if bit_pos != WORD_BITS { - let bit = 1 << bit_pos; - *word ^= bit; - return Some(T::new(bit_pos + offset)) - } - } - - let (i, word) = self.iter.next()?; - self.cur = Some((*word, WORD_BITS * i)); - } - } -} - -#[inline] -fn bitwise(out_vec: &mut [Word], in_vec: &[Word], op: Op) -> bool - where Op: Fn(Word, Word) -> Word -{ - assert_eq!(out_vec.len(), in_vec.len()); - let mut changed = false; - for (out_elem, in_elem) in out_vec.iter_mut().zip(in_vec.iter()) { - let old_val = *out_elem; - let new_val = op(old_val, *in_elem); - *out_elem = new_val; - changed |= old_val != new_val; - } - changed -} - -const SPARSE_MAX: usize = 8; - -/// A fixed-size bitset type with a sparse representation and a maximum of -/// `SPARSE_MAX` elements. The elements are stored as a sorted `SmallVec` with -/// no duplicates; although `SmallVec` can spill its elements to the heap, that -/// never happens within this type because of the `SPARSE_MAX` limit. -/// -/// This type is used by `HybridBitSet`; do not use directly. -#[derive(Clone, Debug)] -pub struct SparseBitSet { - domain_size: usize, - elems: SmallVec<[T; SPARSE_MAX]>, -} - -impl SparseBitSet { - fn new_empty(domain_size: usize) -> Self { - SparseBitSet { - domain_size, - elems: SmallVec::new() - } - } - - fn len(&self) -> usize { - self.elems.len() - } - - fn is_empty(&self) -> bool { - self.elems.len() == 0 - } - - fn contains(&self, elem: T) -> bool { - assert!(elem.index() < self.domain_size); - self.elems.contains(&elem) - } - - fn insert(&mut self, elem: T) -> bool { - assert!(elem.index() < self.domain_size); - let changed = if let Some(i) = self.elems.iter().position(|&e| e >= elem) { - if self.elems[i] == elem { - // `elem` is already in the set. - false - } else { - // `elem` is smaller than one or more existing elements. - self.elems.insert(i, elem); - true - } - } else { - // `elem` is larger than all existing elements. - self.elems.push(elem); - true - }; - assert!(self.len() <= SPARSE_MAX); - changed - } - - fn remove(&mut self, elem: T) -> bool { - assert!(elem.index() < self.domain_size); - if let Some(i) = self.elems.iter().position(|&e| e == elem) { - self.elems.remove(i); - true - } else { - false - } - } - - fn to_dense(&self) -> BitSet { - let mut dense = BitSet::new_empty(self.domain_size); - for elem in self.elems.iter() { - dense.insert(*elem); - } - dense - } - - fn iter(&self) -> slice::Iter<'_, T> { - self.elems.iter() - } -} - -impl UnionIntoBitSet for SparseBitSet { - fn union_into(&self, other: &mut BitSet) -> bool { - assert_eq!(self.domain_size, other.domain_size); - let mut changed = false; - for elem in self.iter() { - changed |= other.insert(*elem); - } - changed - } -} - -impl SubtractFromBitSet for SparseBitSet { - fn subtract_from(&self, other: &mut BitSet) -> bool { - assert_eq!(self.domain_size, other.domain_size); - let mut changed = false; - for elem in self.iter() { - changed |= other.remove(*elem); - } - changed - } -} - -/// A fixed-size bitset type with a hybrid representation: sparse when there -/// are up to a `SPARSE_MAX` elements in the set, but dense when there are more -/// than `SPARSE_MAX`. -/// -/// This type is especially efficient for sets that typically have a small -/// number of elements, but a large `domain_size`, and are cleared frequently. -/// -/// `T` is an index type, typically a newtyped `usize` wrapper, but it can also -/// just be `usize`. -/// -/// All operations that involve an element will panic if the element is equal -/// to or greater than the domain size. All operations that involve two bitsets -/// will panic if the bitsets have differing domain sizes. -#[derive(Clone, Debug)] -pub enum HybridBitSet { - Sparse(SparseBitSet), - Dense(BitSet), -} - -impl HybridBitSet { - pub fn new_empty(domain_size: usize) -> Self { - HybridBitSet::Sparse(SparseBitSet::new_empty(domain_size)) - } - - fn domain_size(&self) -> usize { - match self { - HybridBitSet::Sparse(sparse) => sparse.domain_size, - HybridBitSet::Dense(dense) => dense.domain_size, - } - } - - pub fn clear(&mut self) { - let domain_size = self.domain_size(); - *self = HybridBitSet::new_empty(domain_size); - } - - pub fn contains(&self, elem: T) -> bool { - match self { - HybridBitSet::Sparse(sparse) => sparse.contains(elem), - HybridBitSet::Dense(dense) => dense.contains(elem), - } - } - - pub fn superset(&self, other: &HybridBitSet) -> bool { - match (self, other) { - (HybridBitSet::Dense(self_dense), HybridBitSet::Dense(other_dense)) => { - self_dense.superset(other_dense) - } - _ => { - assert!(self.domain_size() == other.domain_size()); - other.iter().all(|elem| self.contains(elem)) - } - } - } - - pub fn is_empty(&self) -> bool { - match self { - HybridBitSet::Sparse(sparse) => sparse.is_empty(), - HybridBitSet::Dense(dense) => dense.is_empty(), - } - } - - pub fn insert(&mut self, elem: T) -> bool { - // No need to check `elem` against `self.domain_size` here because all - // the match cases check it, one way or another. - match self { - HybridBitSet::Sparse(sparse) if sparse.len() < SPARSE_MAX => { - // The set is sparse and has space for `elem`. - sparse.insert(elem) - } - HybridBitSet::Sparse(sparse) if sparse.contains(elem) => { - // The set is sparse and does not have space for `elem`, but - // that doesn't matter because `elem` is already present. - false - } - HybridBitSet::Sparse(sparse) => { - // The set is sparse and full. Convert to a dense set. - let mut dense = sparse.to_dense(); - let changed = dense.insert(elem); - assert!(changed); - *self = HybridBitSet::Dense(dense); - changed - } - HybridBitSet::Dense(dense) => dense.insert(elem), - } - } - - pub fn insert_all(&mut self) { - let domain_size = self.domain_size(); - match self { - HybridBitSet::Sparse(_) => { - *self = HybridBitSet::Dense(BitSet::new_filled(domain_size)); - } - HybridBitSet::Dense(dense) => dense.insert_all(), - } - } - - pub fn remove(&mut self, elem: T) -> bool { - // Note: we currently don't bother going from Dense back to Sparse. - match self { - HybridBitSet::Sparse(sparse) => sparse.remove(elem), - HybridBitSet::Dense(dense) => dense.remove(elem), - } - } - - pub fn union(&mut self, other: &HybridBitSet) -> bool { - match self { - HybridBitSet::Sparse(self_sparse) => { - match other { - HybridBitSet::Sparse(other_sparse) => { - // Both sets are sparse. Add the elements in - // `other_sparse` to `self` one at a time. This - // may or may not cause `self` to be densified. - assert_eq!(self.domain_size(), other.domain_size()); - let mut changed = false; - for elem in other_sparse.iter() { - changed |= self.insert(*elem); - } - changed - } - HybridBitSet::Dense(other_dense) => { - // `self` is sparse and `other` is dense. To - // merge them, we have two available strategies: - // * Densify `self` then merge other - // * Clone other then integrate bits from `self` - // The second strategy requires dedicated method - // since the usual `union` returns the wrong - // result. In the dedicated case the computation - // is slightly faster if the bits of the sparse - // bitset map to only few words of the dense - // representation, i.e. indices are near each - // other. - // - // Benchmarking seems to suggest that the second - // option is worth it. - let mut new_dense = other_dense.clone(); - let changed = new_dense.reverse_union_sparse(self_sparse); - *self = HybridBitSet::Dense(new_dense); - changed - } - } - } - - HybridBitSet::Dense(self_dense) => self_dense.union(other), - } - } - - /// Converts to a dense set, consuming itself in the process. - pub fn to_dense(self) -> BitSet { - match self { - HybridBitSet::Sparse(sparse) => sparse.to_dense(), - HybridBitSet::Dense(dense) => dense, - } - } - - pub fn iter(&self) -> HybridIter<'_, T> { - match self { - HybridBitSet::Sparse(sparse) => HybridIter::Sparse(sparse.iter()), - HybridBitSet::Dense(dense) => HybridIter::Dense(dense.iter()), - } - } -} - -impl UnionIntoBitSet for HybridBitSet { - fn union_into(&self, other: &mut BitSet) -> bool { - match self { - HybridBitSet::Sparse(sparse) => sparse.union_into(other), - HybridBitSet::Dense(dense) => dense.union_into(other), - } - } -} - -impl SubtractFromBitSet for HybridBitSet { - fn subtract_from(&self, other: &mut BitSet) -> bool { - match self { - HybridBitSet::Sparse(sparse) => sparse.subtract_from(other), - HybridBitSet::Dense(dense) => dense.subtract_from(other), - } - } -} - -pub enum HybridIter<'a, T: Idx> { - Sparse(slice::Iter<'a, T>), - Dense(BitIter<'a, T>), -} - -impl<'a, T: Idx> Iterator for HybridIter<'a, T> { - type Item = T; - - fn next(&mut self) -> Option { - match self { - HybridIter::Sparse(sparse) => sparse.next().map(|e| *e), - HybridIter::Dense(dense) => dense.next(), - } - } -} - -/// A resizable bitset type with a dense representation. -/// -/// `T` is an index type, typically a newtyped `usize` wrapper, but it can also -/// just be `usize`. -/// -/// All operations that involve an element will panic if the element is equal -/// to or greater than the domain size. -#[derive(Clone, Debug, PartialEq)] -pub struct GrowableBitSet { - bit_set: BitSet, -} - -impl GrowableBitSet { - /// Ensure that the set can hold at least `min_domain_size` elements. - pub fn ensure(&mut self, min_domain_size: usize) { - if self.bit_set.domain_size < min_domain_size { - self.bit_set.domain_size = min_domain_size; - } - - let min_num_words = num_words(min_domain_size); - if self.bit_set.words.len() < min_num_words { - self.bit_set.words.resize(min_num_words, 0) - } - } - - pub fn new_empty() -> GrowableBitSet { - GrowableBitSet { bit_set: BitSet::new_empty(0) } - } - - pub fn with_capacity(capacity: usize) -> GrowableBitSet { - GrowableBitSet { bit_set: BitSet::new_empty(capacity) } - } - - /// Returns `true` if the set has changed. - #[inline] - pub fn insert(&mut self, elem: T) -> bool { - self.ensure(elem.index() + 1); - self.bit_set.insert(elem) - } - - #[inline] - pub fn contains(&self, elem: T) -> bool { - let (word_index, mask) = word_index_and_mask(elem); - if let Some(word) = self.bit_set.words.get(word_index) { - (word & mask) != 0 - } else { - false - } - } -} - -/// A fixed-size 2D bit matrix type with a dense representation. -/// -/// `R` and `C` are index types used to identify rows and columns respectively; -/// typically newtyped `usize` wrappers, but they can also just be `usize`. -/// -/// All operations that involve a row and/or column index will panic if the -/// index exceeds the relevant bound. -#[derive(Clone, Debug, Eq, PartialEq, RustcDecodable, RustcEncodable)] -pub struct BitMatrix { - num_rows: usize, - num_columns: usize, - words: Vec, - marker: PhantomData<(R, C)>, -} - -impl BitMatrix { - /// Creates a new `rows x columns` matrix, initially empty. - pub fn new(num_rows: usize, num_columns: usize) -> BitMatrix { - // For every element, we need one bit for every other - // element. Round up to an even number of words. - let words_per_row = num_words(num_columns); - BitMatrix { - num_rows, - num_columns, - words: vec![0; num_rows * words_per_row], - marker: PhantomData, - } - } - - /// Creates a new matrix, with `row` used as the value for every row. - pub fn from_row_n(row: &BitSet, num_rows: usize) -> BitMatrix { - let num_columns = row.domain_size(); - let words_per_row = num_words(num_columns); - assert_eq!(words_per_row, row.words().len()); - BitMatrix { - num_rows, - num_columns, - words: iter::repeat(row.words()).take(num_rows).flatten().cloned().collect(), - marker: PhantomData, - } - } - - pub fn rows(&self) -> impl Iterator { - (0..self.num_rows).map(R::new) - } - - /// The range of bits for a given row. - fn range(&self, row: R) -> (usize, usize) { - let words_per_row = num_words(self.num_columns); - let start = row.index() * words_per_row; - (start, start + words_per_row) - } - - /// Sets the cell at `(row, column)` to true. Put another way, insert - /// `column` to the bitset for `row`. - /// - /// Returns `true` if this changed the matrix. - pub fn insert(&mut self, row: R, column: C) -> bool { - assert!(row.index() < self.num_rows && column.index() < self.num_columns); - let (start, _) = self.range(row); - let (word_index, mask) = word_index_and_mask(column); - let words = &mut self.words[..]; - let word = words[start + word_index]; - let new_word = word | mask; - words[start + word_index] = new_word; - word != new_word - } - - /// Do the bits from `row` contain `column`? Put another way, is - /// the matrix cell at `(row, column)` true? Put yet another way, - /// if the matrix represents (transitive) reachability, can - /// `row` reach `column`? - pub fn contains(&self, row: R, column: C) -> bool { - assert!(row.index() < self.num_rows && column.index() < self.num_columns); - let (start, _) = self.range(row); - let (word_index, mask) = word_index_and_mask(column); - (self.words[start + word_index] & mask) != 0 - } - - /// Returns those indices that are true in rows `a` and `b`. This - /// is an O(n) operation where `n` is the number of elements - /// (somewhat independent from the actual size of the - /// intersection, in particular). - pub fn intersect_rows(&self, row1: R, row2: R) -> Vec { - assert!(row1.index() < self.num_rows && row2.index() < self.num_rows); - let (row1_start, row1_end) = self.range(row1); - let (row2_start, row2_end) = self.range(row2); - let mut result = Vec::with_capacity(self.num_columns); - for (base, (i, j)) in (row1_start..row1_end).zip(row2_start..row2_end).enumerate() { - let mut v = self.words[i] & self.words[j]; - for bit in 0..WORD_BITS { - if v == 0 { - break; - } - if v & 0x1 != 0 { - result.push(C::new(base * WORD_BITS + bit)); - } - v >>= 1; - } - } - result - } - - /// Adds the bits from row `read` to the bits from row `write`, and - /// returns `true` if anything changed. - /// - /// This is used when computing transitive reachability because if - /// you have an edge `write -> read`, because in that case - /// `write` can reach everything that `read` can (and - /// potentially more). - pub fn union_rows(&mut self, read: R, write: R) -> bool { - assert!(read.index() < self.num_rows && write.index() < self.num_rows); - let (read_start, read_end) = self.range(read); - let (write_start, write_end) = self.range(write); - let words = &mut self.words[..]; - let mut changed = false; - for (read_index, write_index) in (read_start..read_end).zip(write_start..write_end) { - let word = words[write_index]; - let new_word = word | words[read_index]; - words[write_index] = new_word; - changed |= word != new_word; - } - changed - } - - /// Adds the bits from `with` to the bits from row `write`, and - /// returns `true` if anything changed. - pub fn union_row_with(&mut self, with: &BitSet, write: R) -> bool { - assert!(write.index() < self.num_rows); - assert_eq!(with.domain_size(), self.num_columns); - let (write_start, write_end) = self.range(write); - let mut changed = false; - for (read_index, write_index) in (0..with.words().len()).zip(write_start..write_end) { - let word = self.words[write_index]; - let new_word = word | with.words()[read_index]; - self.words[write_index] = new_word; - changed |= word != new_word; - } - changed - } - - /// Sets every cell in `row` to true. - pub fn insert_all_into_row(&mut self, row: R) { - assert!(row.index() < self.num_rows); - let (start, end) = self.range(row); - let words = &mut self.words[..]; - for index in start..end { - words[index] = !0; - } - self.clear_excess_bits(row); - } - - /// Clear excess bits in the final word of the row. - fn clear_excess_bits(&mut self, row: R) { - let num_bits_in_final_word = self.num_columns % WORD_BITS; - if num_bits_in_final_word > 0 { - let mask = (1 << num_bits_in_final_word) - 1; - let (_, end) = self.range(row); - let final_word_idx = end - 1; - self.words[final_word_idx] &= mask; - } - } - - /// Gets a slice of the underlying words. - pub fn words(&self) -> &[Word] { - &self.words - } - - /// Iterates through all the columns set to true in a given row of - /// the matrix. - pub fn iter(&self, row: R) -> BitIter<'_, C> { - assert!(row.index() < self.num_rows); - let (start, end) = self.range(row); - BitIter { - cur: None, - iter: self.words[start..end].iter().enumerate(), - marker: PhantomData, - } - } - - /// Returns the number of elements in `row`. - pub fn count(&self, row: R) -> usize { - let (start, end) = self.range(row); - self.words[start..end].iter().map(|e| e.count_ones() as usize).sum() - } -} - -/// A fixed-column-size, variable-row-size 2D bit matrix with a moderately -/// sparse representation. -/// -/// Initially, every row has no explicit representation. If any bit within a -/// row is set, the entire row is instantiated as `Some()`. -/// Furthermore, any previously uninstantiated rows prior to it will be -/// instantiated as `None`. Those prior rows may themselves become fully -/// instantiated later on if any of their bits are set. -/// -/// `R` and `C` are index types used to identify rows and columns respectively; -/// typically newtyped `usize` wrappers, but they can also just be `usize`. -#[derive(Clone, Debug)] -pub struct SparseBitMatrix -where - R: Idx, - C: Idx, -{ - num_columns: usize, - rows: IndexVec>>, -} - -impl SparseBitMatrix { - /// Creates a new empty sparse bit matrix with no rows or columns. - pub fn new(num_columns: usize) -> Self { - Self { - num_columns, - rows: IndexVec::new(), - } - } - - fn ensure_row(&mut self, row: R) -> &mut HybridBitSet { - // Instantiate any missing rows up to and including row `row` with an - // empty HybridBitSet. - self.rows.ensure_contains_elem(row, || None); - - // Then replace row `row` with a full HybridBitSet if necessary. - let num_columns = self.num_columns; - self.rows[row].get_or_insert_with(|| HybridBitSet::new_empty(num_columns)) - } - - /// Sets the cell at `(row, column)` to true. Put another way, insert - /// `column` to the bitset for `row`. - /// - /// Returns `true` if this changed the matrix. - pub fn insert(&mut self, row: R, column: C) -> bool { - self.ensure_row(row).insert(column) - } - - /// Do the bits from `row` contain `column`? Put another way, is - /// the matrix cell at `(row, column)` true? Put yet another way, - /// if the matrix represents (transitive) reachability, can - /// `row` reach `column`? - pub fn contains(&self, row: R, column: C) -> bool { - self.row(row).map_or(false, |r| r.contains(column)) - } - - /// Adds the bits from row `read` to the bits from row `write`, and - /// returns `true` if anything changed. - /// - /// This is used when computing transitive reachability because if - /// you have an edge `write -> read`, because in that case - /// `write` can reach everything that `read` can (and - /// potentially more). - pub fn union_rows(&mut self, read: R, write: R) -> bool { - if read == write || self.row(read).is_none() { - return false; - } - - self.ensure_row(write); - if let (Some(read_row), Some(write_row)) = self.rows.pick2_mut(read, write) { - write_row.union(read_row) - } else { - unreachable!() - } - } - - /// Union a row, `from`, into the `into` row. - pub fn union_into_row(&mut self, into: R, from: &HybridBitSet) -> bool { - self.ensure_row(into).union(from) - } - - /// Insert all bits in the given row. - pub fn insert_all_into_row(&mut self, row: R) { - self.ensure_row(row).insert_all(); - } - - pub fn rows(&self) -> impl Iterator { - self.rows.indices() - } - - /// Iterates through all the columns set to true in a given row of - /// the matrix. - pub fn iter<'a>(&'a self, row: R) -> impl Iterator + 'a { - self.row(row).into_iter().flat_map(|r| r.iter()) - } - - pub fn row(&self, row: R) -> Option<&HybridBitSet> { - if let Some(Some(row)) = self.rows.get(row) { - Some(row) - } else { - None - } - } -} - -#[inline] -fn num_words(domain_size: T) -> usize { - (domain_size.index() + WORD_BITS - 1) / WORD_BITS -} - -#[inline] -fn word_index_and_mask(elem: T) -> (usize, Word) { - let elem = elem.index(); - let word_index = elem / WORD_BITS; - let mask = 1 << (elem % WORD_BITS); - (word_index, mask) -} diff --git a/src/librustc_data_structures/bit_set/tests.rs b/src/librustc_data_structures/bit_set/tests.rs deleted file mode 100644 index ac7913815ff..00000000000 --- a/src/librustc_data_structures/bit_set/tests.rs +++ /dev/null @@ -1,369 +0,0 @@ -use super::*; - -extern crate test; -use test::Bencher; - -#[test] -fn test_new_filled() { - for i in 0..128 { - let idx_buf = BitSet::new_filled(i); - let elems: Vec = idx_buf.iter().collect(); - let expected: Vec = (0..i).collect(); - assert_eq!(elems, expected); - } -} - -#[test] -fn bitset_iter_works() { - let mut bitset: BitSet = BitSet::new_empty(100); - bitset.insert(1); - bitset.insert(10); - bitset.insert(19); - bitset.insert(62); - bitset.insert(63); - bitset.insert(64); - bitset.insert(65); - bitset.insert(66); - bitset.insert(99); - assert_eq!( - bitset.iter().collect::>(), - [1, 10, 19, 62, 63, 64, 65, 66, 99] - ); -} - -#[test] -fn bitset_iter_works_2() { - let mut bitset: BitSet = BitSet::new_empty(320); - bitset.insert(0); - bitset.insert(127); - bitset.insert(191); - bitset.insert(255); - bitset.insert(319); - assert_eq!(bitset.iter().collect::>(), [0, 127, 191, 255, 319]); -} - -#[test] -fn union_two_sets() { - let mut set1: BitSet = BitSet::new_empty(65); - let mut set2: BitSet = BitSet::new_empty(65); - assert!(set1.insert(3)); - assert!(!set1.insert(3)); - assert!(set2.insert(5)); - assert!(set2.insert(64)); - assert!(set1.union(&set2)); - assert!(!set1.union(&set2)); - assert!(set1.contains(3)); - assert!(!set1.contains(4)); - assert!(set1.contains(5)); - assert!(!set1.contains(63)); - assert!(set1.contains(64)); -} - -#[test] -fn hybrid_bitset() { - let mut sparse038: HybridBitSet = HybridBitSet::new_empty(256); - assert!(sparse038.is_empty()); - assert!(sparse038.insert(0)); - assert!(sparse038.insert(1)); - assert!(sparse038.insert(8)); - assert!(sparse038.insert(3)); - assert!(!sparse038.insert(3)); - assert!(sparse038.remove(1)); - assert!(!sparse038.is_empty()); - assert_eq!(sparse038.iter().collect::>(), [0, 3, 8]); - - for i in 0..256 { - if i == 0 || i == 3 || i == 8 { - assert!(sparse038.contains(i)); - } else { - assert!(!sparse038.contains(i)); - } - } - - let mut sparse01358 = sparse038.clone(); - assert!(sparse01358.insert(1)); - assert!(sparse01358.insert(5)); - assert_eq!(sparse01358.iter().collect::>(), [0, 1, 3, 5, 8]); - - let mut dense10 = HybridBitSet::new_empty(256); - for i in 0..10 { - assert!(dense10.insert(i)); - } - assert!(!dense10.is_empty()); - assert_eq!(dense10.iter().collect::>(), [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); - - let mut dense256 = HybridBitSet::new_empty(256); - assert!(dense256.is_empty()); - dense256.insert_all(); - assert!(!dense256.is_empty()); - for i in 0..256 { - assert!(dense256.contains(i)); - } - - assert!(sparse038.superset(&sparse038)); // sparse + sparse (self) - assert!(sparse01358.superset(&sparse038)); // sparse + sparse - assert!(dense10.superset(&sparse038)); // dense + sparse - assert!(dense10.superset(&dense10)); // dense + dense (self) - assert!(dense256.superset(&dense10)); // dense + dense - - let mut hybrid = sparse038; - assert!(!sparse01358.union(&hybrid)); // no change - assert!(hybrid.union(&sparse01358)); - assert!(hybrid.superset(&sparse01358) && sparse01358.superset(&hybrid)); - assert!(!dense10.union(&sparse01358)); - assert!(!dense256.union(&dense10)); - let mut dense = dense10; - assert!(dense.union(&dense256)); - assert!(dense.superset(&dense256) && dense256.superset(&dense)); - assert!(hybrid.union(&dense256)); - assert!(hybrid.superset(&dense256) && dense256.superset(&hybrid)); - - assert_eq!(dense256.iter().count(), 256); - let mut dense0 = dense256; - for i in 0..256 { - assert!(dense0.remove(i)); - } - assert!(!dense0.remove(0)); - assert!(dense0.is_empty()); -} - -#[test] -fn grow() { - let mut set: GrowableBitSet = GrowableBitSet::with_capacity(65); - for index in 0..65 { - assert!(set.insert(index)); - assert!(!set.insert(index)); - } - set.ensure(128); - - // Check if the bits set before growing are still set - for index in 0..65 { - assert!(set.contains(index)); - } - - // Check if the new bits are all un-set - for index in 65..128 { - assert!(!set.contains(index)); - } - - // Check that we can set all new bits without running out of bounds - for index in 65..128 { - assert!(set.insert(index)); - assert!(!set.insert(index)); - } -} - -#[test] -fn matrix_intersection() { - let mut matrix: BitMatrix = BitMatrix::new(200, 200); - - // (*) Elements reachable from both 2 and 65. - - matrix.insert(2, 3); - matrix.insert(2, 6); - matrix.insert(2, 10); // (*) - matrix.insert(2, 64); // (*) - matrix.insert(2, 65); - matrix.insert(2, 130); - matrix.insert(2, 160); // (*) - - matrix.insert(64, 133); - - matrix.insert(65, 2); - matrix.insert(65, 8); - matrix.insert(65, 10); // (*) - matrix.insert(65, 64); // (*) - matrix.insert(65, 68); - matrix.insert(65, 133); - matrix.insert(65, 160); // (*) - - let intersection = matrix.intersect_rows(2, 64); - assert!(intersection.is_empty()); - - let intersection = matrix.intersect_rows(2, 65); - assert_eq!(intersection, &[10, 64, 160]); -} - -#[test] -fn matrix_iter() { - let mut matrix: BitMatrix = BitMatrix::new(64, 100); - matrix.insert(3, 22); - matrix.insert(3, 75); - matrix.insert(2, 99); - matrix.insert(4, 0); - matrix.union_rows(3, 5); - matrix.insert_all_into_row(6); - - let expected = [99]; - let mut iter = expected.iter(); - for i in matrix.iter(2) { - let j = *iter.next().unwrap(); - assert_eq!(i, j); - } - assert!(iter.next().is_none()); - - let expected = [22, 75]; - let mut iter = expected.iter(); - assert_eq!(matrix.count(3), expected.len()); - for i in matrix.iter(3) { - let j = *iter.next().unwrap(); - assert_eq!(i, j); - } - assert!(iter.next().is_none()); - - let expected = [0]; - let mut iter = expected.iter(); - assert_eq!(matrix.count(4), expected.len()); - for i in matrix.iter(4) { - let j = *iter.next().unwrap(); - assert_eq!(i, j); - } - assert!(iter.next().is_none()); - - let expected = [22, 75]; - let mut iter = expected.iter(); - assert_eq!(matrix.count(5), expected.len()); - for i in matrix.iter(5) { - let j = *iter.next().unwrap(); - assert_eq!(i, j); - } - assert!(iter.next().is_none()); - - assert_eq!(matrix.count(6), 100); - let mut count = 0; - for (idx, i) in matrix.iter(6).enumerate() { - assert_eq!(idx, i); - count += 1; - } - assert_eq!(count, 100); - - if let Some(i) = matrix.iter(7).next() { - panic!("expected no elements in row, but contains element {:?}", i); - } -} - -#[test] -fn sparse_matrix_iter() { - let mut matrix: SparseBitMatrix = SparseBitMatrix::new(100); - matrix.insert(3, 22); - matrix.insert(3, 75); - matrix.insert(2, 99); - matrix.insert(4, 0); - matrix.union_rows(3, 5); - - let expected = [99]; - let mut iter = expected.iter(); - for i in matrix.iter(2) { - let j = *iter.next().unwrap(); - assert_eq!(i, j); - } - assert!(iter.next().is_none()); - - let expected = [22, 75]; - let mut iter = expected.iter(); - for i in matrix.iter(3) { - let j = *iter.next().unwrap(); - assert_eq!(i, j); - } - assert!(iter.next().is_none()); - - let expected = [0]; - let mut iter = expected.iter(); - for i in matrix.iter(4) { - let j = *iter.next().unwrap(); - assert_eq!(i, j); - } - assert!(iter.next().is_none()); - - let expected = [22, 75]; - let mut iter = expected.iter(); - for i in matrix.iter(5) { - let j = *iter.next().unwrap(); - assert_eq!(i, j); - } - assert!(iter.next().is_none()); -} - -/// Merge dense hybrid set into empty sparse hybrid set. -#[bench] -fn union_hybrid_sparse_empty_to_dense(b: &mut Bencher) { - let mut pre_dense: HybridBitSet = HybridBitSet::new_empty(256); - for i in 0..10 { - assert!(pre_dense.insert(i)); - } - let pre_sparse: HybridBitSet = HybridBitSet::new_empty(256); - b.iter(|| { - let dense = pre_dense.clone(); - let mut sparse = pre_sparse.clone(); - sparse.union(&dense); - }) -} - -/// Merge dense hybrid set into full hybrid set with same indices. -#[bench] -fn union_hybrid_sparse_full_to_dense(b: &mut Bencher) { - let mut pre_dense: HybridBitSet = HybridBitSet::new_empty(256); - for i in 0..10 { - assert!(pre_dense.insert(i)); - } - let mut pre_sparse: HybridBitSet = HybridBitSet::new_empty(256); - for i in 0..SPARSE_MAX { - assert!(pre_sparse.insert(i)); - } - b.iter(|| { - let dense = pre_dense.clone(); - let mut sparse = pre_sparse.clone(); - sparse.union(&dense); - }) -} - -/// Merge dense hybrid set into full hybrid set with indices over the whole domain. -#[bench] -fn union_hybrid_sparse_domain_to_dense(b: &mut Bencher) { - let mut pre_dense: HybridBitSet = HybridBitSet::new_empty(SPARSE_MAX*64); - for i in 0..10 { - assert!(pre_dense.insert(i)); - } - let mut pre_sparse: HybridBitSet = HybridBitSet::new_empty(SPARSE_MAX*64); - for i in 0..SPARSE_MAX { - assert!(pre_sparse.insert(i*64)); - } - b.iter(|| { - let dense = pre_dense.clone(); - let mut sparse = pre_sparse.clone(); - sparse.union(&dense); - }) -} - -/// Merge dense hybrid set into empty hybrid set where the domain is very small. -#[bench] -fn union_hybrid_sparse_empty_small_domain(b: &mut Bencher) { - let mut pre_dense: HybridBitSet = HybridBitSet::new_empty(SPARSE_MAX); - for i in 0..SPARSE_MAX { - assert!(pre_dense.insert(i)); - } - let pre_sparse: HybridBitSet = HybridBitSet::new_empty(SPARSE_MAX); - b.iter(|| { - let dense = pre_dense.clone(); - let mut sparse = pre_sparse.clone(); - sparse.union(&dense); - }) -} - -/// Merge dense hybrid set into full hybrid set where the domain is very small. -#[bench] -fn union_hybrid_sparse_full_small_domain(b: &mut Bencher) { - let mut pre_dense: HybridBitSet = HybridBitSet::new_empty(SPARSE_MAX); - for i in 0..SPARSE_MAX { - assert!(pre_dense.insert(i)); - } - let mut pre_sparse: HybridBitSet = HybridBitSet::new_empty(SPARSE_MAX); - for i in 0..SPARSE_MAX { - assert!(pre_sparse.insert(i)); - } - b.iter(|| { - let dense = pre_dense.clone(); - let mut sparse = pre_sparse.clone(); - sparse.union(&dense); - }) -} diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index a9ef297fa99..e28ee48201c 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -37,7 +37,7 @@ extern crate libc; extern crate cfg_if; pub use rustc_serialize::hex::ToHex; -pub use rustc_index::{indexed_vec, newtype_index}; +pub use rustc_index::{bit_set, indexed_vec, newtype_index}; #[inline(never)] #[cold] @@ -69,7 +69,6 @@ pub mod macros; pub mod svh; pub mod base_n; pub mod binary_search_util; -pub mod bit_set; pub mod box_region; pub mod const_cstr; pub mod flock; diff --git a/src/librustc_index/Cargo.toml b/src/librustc_index/Cargo.toml index 10e66ffe590..b1ebc95e488 100644 --- a/src/librustc_index/Cargo.toml +++ b/src/librustc_index/Cargo.toml @@ -11,3 +11,4 @@ doctest = false [dependencies] rustc_serialize = { path = "../libserialize", package = "serialize" } +smallvec = { version = "0.6.7", features = ["union", "may_dangle"] } diff --git a/src/librustc_index/bit_set.rs b/src/librustc_index/bit_set.rs new file mode 100644 index 00000000000..fe8ef642430 --- /dev/null +++ b/src/librustc_index/bit_set.rs @@ -0,0 +1,984 @@ +use crate::indexed_vec::{Idx, IndexVec}; +use smallvec::SmallVec; +use std::fmt; +use std::iter; +use std::marker::PhantomData; +use std::mem; +use std::slice; + +#[cfg(test)] +mod tests; + +pub type Word = u64; +pub const WORD_BYTES: usize = mem::size_of::(); +pub const WORD_BITS: usize = WORD_BYTES * 8; + +/// A fixed-size bitset type with a dense representation. It does not support +/// resizing after creation; use `GrowableBitSet` for that. +/// +/// `T` is an index type, typically a newtyped `usize` wrapper, but it can also +/// just be `usize`. +/// +/// All operations that involve an element will panic if the element is equal +/// to or greater than the domain size. All operations that involve two bitsets +/// will panic if the bitsets have differing domain sizes. +#[derive(Clone, Eq, PartialEq, RustcDecodable, RustcEncodable)] +pub struct BitSet { + domain_size: usize, + words: Vec, + marker: PhantomData, +} + +impl BitSet { + /// Creates a new, empty bitset with a given `domain_size`. + #[inline] + pub fn new_empty(domain_size: usize) -> BitSet { + let num_words = num_words(domain_size); + BitSet { + domain_size, + words: vec![0; num_words], + marker: PhantomData, + } + } + + /// Creates a new, filled bitset with a given `domain_size`. + #[inline] + pub fn new_filled(domain_size: usize) -> BitSet { + let num_words = num_words(domain_size); + let mut result = BitSet { + domain_size, + words: vec![!0; num_words], + marker: PhantomData, + }; + result.clear_excess_bits(); + result + } + + /// Gets the domain size. + pub fn domain_size(&self) -> usize { + self.domain_size + } + + /// Clear all elements. + #[inline] + pub fn clear(&mut self) { + for word in &mut self.words { + *word = 0; + } + } + + /// Clear excess bits in the final word. + fn clear_excess_bits(&mut self) { + let num_bits_in_final_word = self.domain_size % WORD_BITS; + if num_bits_in_final_word > 0 { + let mask = (1 << num_bits_in_final_word) - 1; + let final_word_idx = self.words.len() - 1; + self.words[final_word_idx] &= mask; + } + } + + /// Efficiently overwrite `self` with `other`. + pub fn overwrite(&mut self, other: &BitSet) { + assert!(self.domain_size == other.domain_size); + self.words.clone_from_slice(&other.words); + } + + /// Count the number of set bits in the set. + pub fn count(&self) -> usize { + self.words.iter().map(|e| e.count_ones() as usize).sum() + } + + /// Returns `true` if `self` contains `elem`. + #[inline] + pub fn contains(&self, elem: T) -> bool { + assert!(elem.index() < self.domain_size); + let (word_index, mask) = word_index_and_mask(elem); + (self.words[word_index] & mask) != 0 + } + + /// Is `self` is a (non-strict) superset of `other`? + #[inline] + pub fn superset(&self, other: &BitSet) -> bool { + assert_eq!(self.domain_size, other.domain_size); + self.words.iter().zip(&other.words).all(|(a, b)| (a & b) == *b) + } + + /// Is the set empty? + #[inline] + pub fn is_empty(&self) -> bool { + self.words.iter().all(|a| *a == 0) + } + + /// Insert `elem`. Returns whether the set has changed. + #[inline] + pub fn insert(&mut self, elem: T) -> bool { + assert!(elem.index() < self.domain_size); + let (word_index, mask) = word_index_and_mask(elem); + let word_ref = &mut self.words[word_index]; + let word = *word_ref; + let new_word = word | mask; + *word_ref = new_word; + new_word != word + } + + /// Sets all bits to true. + pub fn insert_all(&mut self) { + for word in &mut self.words { + *word = !0; + } + self.clear_excess_bits(); + } + + /// Returns `true` if the set has changed. + #[inline] + pub fn remove(&mut self, elem: T) -> bool { + assert!(elem.index() < self.domain_size); + let (word_index, mask) = word_index_and_mask(elem); + let word_ref = &mut self.words[word_index]; + let word = *word_ref; + let new_word = word & !mask; + *word_ref = new_word; + new_word != word + } + + /// Sets `self = self | other` and returns `true` if `self` changed + /// (i.e., if new bits were added). + pub fn union(&mut self, other: &impl UnionIntoBitSet) -> bool { + other.union_into(self) + } + + /// Sets `self = self - other` and returns `true` if `self` changed. + /// (i.e., if any bits were removed). + pub fn subtract(&mut self, other: &impl SubtractFromBitSet) -> bool { + other.subtract_from(self) + } + + /// Sets `self = self & other` and return `true` if `self` changed. + /// (i.e., if any bits were removed). + pub fn intersect(&mut self, other: &BitSet) -> bool { + assert_eq!(self.domain_size, other.domain_size); + bitwise(&mut self.words, &other.words, |a, b| { a & b }) + } + + /// Gets a slice of the underlying words. + pub fn words(&self) -> &[Word] { + &self.words + } + + /// Iterates over the indices of set bits in a sorted order. + #[inline] + pub fn iter(&self) -> BitIter<'_, T> { + BitIter { + cur: None, + iter: self.words.iter().enumerate(), + marker: PhantomData, + } + } + + /// Duplicates the set as a hybrid set. + pub fn to_hybrid(&self) -> HybridBitSet { + // Note: we currently don't bother trying to make a Sparse set. + HybridBitSet::Dense(self.to_owned()) + } + + /// Set `self = self | other`. In contrast to `union` returns `true` if the set contains at + /// least one bit that is not in `other` (i.e. `other` is not a superset of `self`). + /// + /// This is an optimization for union of a hybrid bitset. + fn reverse_union_sparse(&mut self, sparse: &SparseBitSet) -> bool { + assert!(sparse.domain_size == self.domain_size); + self.clear_excess_bits(); + + let mut not_already = false; + // Index of the current word not yet merged. + let mut current_index = 0; + // Mask of bits that came from the sparse set in the current word. + let mut new_bit_mask = 0; + for (word_index, mask) in sparse.iter().map(|x| word_index_and_mask(*x)) { + // Next bit is in a word not inspected yet. + if word_index > current_index { + self.words[current_index] |= new_bit_mask; + // Were there any bits in the old word that did not occur in the sparse set? + not_already |= (self.words[current_index] ^ new_bit_mask) != 0; + // Check all words we skipped for any set bit. + not_already |= self.words[current_index+1..word_index].iter().any(|&x| x != 0); + // Update next word. + current_index = word_index; + // Reset bit mask, no bits have been merged yet. + new_bit_mask = 0; + } + // Add bit and mark it as coming from the sparse set. + // self.words[word_index] |= mask; + new_bit_mask |= mask; + } + self.words[current_index] |= new_bit_mask; + // Any bits in the last inspected word that were not in the sparse set? + not_already |= (self.words[current_index] ^ new_bit_mask) != 0; + // Any bits in the tail? Note `clear_excess_bits` before. + not_already |= self.words[current_index+1..].iter().any(|&x| x != 0); + + not_already + } +} + +/// This is implemented by all the bitsets so that BitSet::union() can be +/// passed any type of bitset. +pub trait UnionIntoBitSet { + // Performs `other = other | self`. + fn union_into(&self, other: &mut BitSet) -> bool; +} + +/// This is implemented by all the bitsets so that BitSet::subtract() can be +/// passed any type of bitset. +pub trait SubtractFromBitSet { + // Performs `other = other - self`. + fn subtract_from(&self, other: &mut BitSet) -> bool; +} + +impl UnionIntoBitSet for BitSet { + fn union_into(&self, other: &mut BitSet) -> bool { + assert_eq!(self.domain_size, other.domain_size); + bitwise(&mut other.words, &self.words, |a, b| { a | b }) + } +} + +impl SubtractFromBitSet for BitSet { + fn subtract_from(&self, other: &mut BitSet) -> bool { + assert_eq!(self.domain_size, other.domain_size); + bitwise(&mut other.words, &self.words, |a, b| { a & !b }) + } +} + +impl fmt::Debug for BitSet { + fn fmt(&self, w: &mut fmt::Formatter<'_>) -> fmt::Result { + w.debug_list() + .entries(self.iter()) + .finish() + } +} + +impl ToString for BitSet { + fn to_string(&self) -> String { + let mut result = String::new(); + let mut sep = '['; + + // Note: this is a little endian printout of bytes. + + // i tracks how many bits we have printed so far. + let mut i = 0; + for word in &self.words { + let mut word = *word; + for _ in 0..WORD_BYTES { // for each byte in `word`: + let remain = self.domain_size - i; + // If less than a byte remains, then mask just that many bits. + let mask = if remain <= 8 { (1 << remain) - 1 } else { 0xFF }; + assert!(mask <= 0xFF); + let byte = word & mask; + + result.push_str(&format!("{}{:02x}", sep, byte)); + + if remain <= 8 { break; } + word >>= 8; + i += 8; + sep = '-'; + } + sep = '|'; + } + result.push(']'); + + result + } +} + +pub struct BitIter<'a, T: Idx> { + cur: Option<(Word, usize)>, + iter: iter::Enumerate>, + marker: PhantomData +} + +impl<'a, T: Idx> Iterator for BitIter<'a, T> { + type Item = T; + fn next(&mut self) -> Option { + loop { + if let Some((ref mut word, offset)) = self.cur { + let bit_pos = word.trailing_zeros() as usize; + if bit_pos != WORD_BITS { + let bit = 1 << bit_pos; + *word ^= bit; + return Some(T::new(bit_pos + offset)) + } + } + + let (i, word) = self.iter.next()?; + self.cur = Some((*word, WORD_BITS * i)); + } + } +} + +#[inline] +fn bitwise(out_vec: &mut [Word], in_vec: &[Word], op: Op) -> bool + where Op: Fn(Word, Word) -> Word +{ + assert_eq!(out_vec.len(), in_vec.len()); + let mut changed = false; + for (out_elem, in_elem) in out_vec.iter_mut().zip(in_vec.iter()) { + let old_val = *out_elem; + let new_val = op(old_val, *in_elem); + *out_elem = new_val; + changed |= old_val != new_val; + } + changed +} + +const SPARSE_MAX: usize = 8; + +/// A fixed-size bitset type with a sparse representation and a maximum of +/// `SPARSE_MAX` elements. The elements are stored as a sorted `SmallVec` with +/// no duplicates; although `SmallVec` can spill its elements to the heap, that +/// never happens within this type because of the `SPARSE_MAX` limit. +/// +/// This type is used by `HybridBitSet`; do not use directly. +#[derive(Clone, Debug)] +pub struct SparseBitSet { + domain_size: usize, + elems: SmallVec<[T; SPARSE_MAX]>, +} + +impl SparseBitSet { + fn new_empty(domain_size: usize) -> Self { + SparseBitSet { + domain_size, + elems: SmallVec::new() + } + } + + fn len(&self) -> usize { + self.elems.len() + } + + fn is_empty(&self) -> bool { + self.elems.len() == 0 + } + + fn contains(&self, elem: T) -> bool { + assert!(elem.index() < self.domain_size); + self.elems.contains(&elem) + } + + fn insert(&mut self, elem: T) -> bool { + assert!(elem.index() < self.domain_size); + let changed = if let Some(i) = self.elems.iter().position(|&e| e >= elem) { + if self.elems[i] == elem { + // `elem` is already in the set. + false + } else { + // `elem` is smaller than one or more existing elements. + self.elems.insert(i, elem); + true + } + } else { + // `elem` is larger than all existing elements. + self.elems.push(elem); + true + }; + assert!(self.len() <= SPARSE_MAX); + changed + } + + fn remove(&mut self, elem: T) -> bool { + assert!(elem.index() < self.domain_size); + if let Some(i) = self.elems.iter().position(|&e| e == elem) { + self.elems.remove(i); + true + } else { + false + } + } + + fn to_dense(&self) -> BitSet { + let mut dense = BitSet::new_empty(self.domain_size); + for elem in self.elems.iter() { + dense.insert(*elem); + } + dense + } + + fn iter(&self) -> slice::Iter<'_, T> { + self.elems.iter() + } +} + +impl UnionIntoBitSet for SparseBitSet { + fn union_into(&self, other: &mut BitSet) -> bool { + assert_eq!(self.domain_size, other.domain_size); + let mut changed = false; + for elem in self.iter() { + changed |= other.insert(*elem); + } + changed + } +} + +impl SubtractFromBitSet for SparseBitSet { + fn subtract_from(&self, other: &mut BitSet) -> bool { + assert_eq!(self.domain_size, other.domain_size); + let mut changed = false; + for elem in self.iter() { + changed |= other.remove(*elem); + } + changed + } +} + +/// A fixed-size bitset type with a hybrid representation: sparse when there +/// are up to a `SPARSE_MAX` elements in the set, but dense when there are more +/// than `SPARSE_MAX`. +/// +/// This type is especially efficient for sets that typically have a small +/// number of elements, but a large `domain_size`, and are cleared frequently. +/// +/// `T` is an index type, typically a newtyped `usize` wrapper, but it can also +/// just be `usize`. +/// +/// All operations that involve an element will panic if the element is equal +/// to or greater than the domain size. All operations that involve two bitsets +/// will panic if the bitsets have differing domain sizes. +#[derive(Clone, Debug)] +pub enum HybridBitSet { + Sparse(SparseBitSet), + Dense(BitSet), +} + +impl HybridBitSet { + pub fn new_empty(domain_size: usize) -> Self { + HybridBitSet::Sparse(SparseBitSet::new_empty(domain_size)) + } + + fn domain_size(&self) -> usize { + match self { + HybridBitSet::Sparse(sparse) => sparse.domain_size, + HybridBitSet::Dense(dense) => dense.domain_size, + } + } + + pub fn clear(&mut self) { + let domain_size = self.domain_size(); + *self = HybridBitSet::new_empty(domain_size); + } + + pub fn contains(&self, elem: T) -> bool { + match self { + HybridBitSet::Sparse(sparse) => sparse.contains(elem), + HybridBitSet::Dense(dense) => dense.contains(elem), + } + } + + pub fn superset(&self, other: &HybridBitSet) -> bool { + match (self, other) { + (HybridBitSet::Dense(self_dense), HybridBitSet::Dense(other_dense)) => { + self_dense.superset(other_dense) + } + _ => { + assert!(self.domain_size() == other.domain_size()); + other.iter().all(|elem| self.contains(elem)) + } + } + } + + pub fn is_empty(&self) -> bool { + match self { + HybridBitSet::Sparse(sparse) => sparse.is_empty(), + HybridBitSet::Dense(dense) => dense.is_empty(), + } + } + + pub fn insert(&mut self, elem: T) -> bool { + // No need to check `elem` against `self.domain_size` here because all + // the match cases check it, one way or another. + match self { + HybridBitSet::Sparse(sparse) if sparse.len() < SPARSE_MAX => { + // The set is sparse and has space for `elem`. + sparse.insert(elem) + } + HybridBitSet::Sparse(sparse) if sparse.contains(elem) => { + // The set is sparse and does not have space for `elem`, but + // that doesn't matter because `elem` is already present. + false + } + HybridBitSet::Sparse(sparse) => { + // The set is sparse and full. Convert to a dense set. + let mut dense = sparse.to_dense(); + let changed = dense.insert(elem); + assert!(changed); + *self = HybridBitSet::Dense(dense); + changed + } + HybridBitSet::Dense(dense) => dense.insert(elem), + } + } + + pub fn insert_all(&mut self) { + let domain_size = self.domain_size(); + match self { + HybridBitSet::Sparse(_) => { + *self = HybridBitSet::Dense(BitSet::new_filled(domain_size)); + } + HybridBitSet::Dense(dense) => dense.insert_all(), + } + } + + pub fn remove(&mut self, elem: T) -> bool { + // Note: we currently don't bother going from Dense back to Sparse. + match self { + HybridBitSet::Sparse(sparse) => sparse.remove(elem), + HybridBitSet::Dense(dense) => dense.remove(elem), + } + } + + pub fn union(&mut self, other: &HybridBitSet) -> bool { + match self { + HybridBitSet::Sparse(self_sparse) => { + match other { + HybridBitSet::Sparse(other_sparse) => { + // Both sets are sparse. Add the elements in + // `other_sparse` to `self` one at a time. This + // may or may not cause `self` to be densified. + assert_eq!(self.domain_size(), other.domain_size()); + let mut changed = false; + for elem in other_sparse.iter() { + changed |= self.insert(*elem); + } + changed + } + HybridBitSet::Dense(other_dense) => { + // `self` is sparse and `other` is dense. To + // merge them, we have two available strategies: + // * Densify `self` then merge other + // * Clone other then integrate bits from `self` + // The second strategy requires dedicated method + // since the usual `union` returns the wrong + // result. In the dedicated case the computation + // is slightly faster if the bits of the sparse + // bitset map to only few words of the dense + // representation, i.e. indices are near each + // other. + // + // Benchmarking seems to suggest that the second + // option is worth it. + let mut new_dense = other_dense.clone(); + let changed = new_dense.reverse_union_sparse(self_sparse); + *self = HybridBitSet::Dense(new_dense); + changed + } + } + } + + HybridBitSet::Dense(self_dense) => self_dense.union(other), + } + } + + /// Converts to a dense set, consuming itself in the process. + pub fn to_dense(self) -> BitSet { + match self { + HybridBitSet::Sparse(sparse) => sparse.to_dense(), + HybridBitSet::Dense(dense) => dense, + } + } + + pub fn iter(&self) -> HybridIter<'_, T> { + match self { + HybridBitSet::Sparse(sparse) => HybridIter::Sparse(sparse.iter()), + HybridBitSet::Dense(dense) => HybridIter::Dense(dense.iter()), + } + } +} + +impl UnionIntoBitSet for HybridBitSet { + fn union_into(&self, other: &mut BitSet) -> bool { + match self { + HybridBitSet::Sparse(sparse) => sparse.union_into(other), + HybridBitSet::Dense(dense) => dense.union_into(other), + } + } +} + +impl SubtractFromBitSet for HybridBitSet { + fn subtract_from(&self, other: &mut BitSet) -> bool { + match self { + HybridBitSet::Sparse(sparse) => sparse.subtract_from(other), + HybridBitSet::Dense(dense) => dense.subtract_from(other), + } + } +} + +pub enum HybridIter<'a, T: Idx> { + Sparse(slice::Iter<'a, T>), + Dense(BitIter<'a, T>), +} + +impl<'a, T: Idx> Iterator for HybridIter<'a, T> { + type Item = T; + + fn next(&mut self) -> Option { + match self { + HybridIter::Sparse(sparse) => sparse.next().map(|e| *e), + HybridIter::Dense(dense) => dense.next(), + } + } +} + +/// A resizable bitset type with a dense representation. +/// +/// `T` is an index type, typically a newtyped `usize` wrapper, but it can also +/// just be `usize`. +/// +/// All operations that involve an element will panic if the element is equal +/// to or greater than the domain size. +#[derive(Clone, Debug, PartialEq)] +pub struct GrowableBitSet { + bit_set: BitSet, +} + +impl GrowableBitSet { + /// Ensure that the set can hold at least `min_domain_size` elements. + pub fn ensure(&mut self, min_domain_size: usize) { + if self.bit_set.domain_size < min_domain_size { + self.bit_set.domain_size = min_domain_size; + } + + let min_num_words = num_words(min_domain_size); + if self.bit_set.words.len() < min_num_words { + self.bit_set.words.resize(min_num_words, 0) + } + } + + pub fn new_empty() -> GrowableBitSet { + GrowableBitSet { bit_set: BitSet::new_empty(0) } + } + + pub fn with_capacity(capacity: usize) -> GrowableBitSet { + GrowableBitSet { bit_set: BitSet::new_empty(capacity) } + } + + /// Returns `true` if the set has changed. + #[inline] + pub fn insert(&mut self, elem: T) -> bool { + self.ensure(elem.index() + 1); + self.bit_set.insert(elem) + } + + #[inline] + pub fn contains(&self, elem: T) -> bool { + let (word_index, mask) = word_index_and_mask(elem); + if let Some(word) = self.bit_set.words.get(word_index) { + (word & mask) != 0 + } else { + false + } + } +} + +/// A fixed-size 2D bit matrix type with a dense representation. +/// +/// `R` and `C` are index types used to identify rows and columns respectively; +/// typically newtyped `usize` wrappers, but they can also just be `usize`. +/// +/// All operations that involve a row and/or column index will panic if the +/// index exceeds the relevant bound. +#[derive(Clone, Debug, Eq, PartialEq, RustcDecodable, RustcEncodable)] +pub struct BitMatrix { + num_rows: usize, + num_columns: usize, + words: Vec, + marker: PhantomData<(R, C)>, +} + +impl BitMatrix { + /// Creates a new `rows x columns` matrix, initially empty. + pub fn new(num_rows: usize, num_columns: usize) -> BitMatrix { + // For every element, we need one bit for every other + // element. Round up to an even number of words. + let words_per_row = num_words(num_columns); + BitMatrix { + num_rows, + num_columns, + words: vec![0; num_rows * words_per_row], + marker: PhantomData, + } + } + + /// Creates a new matrix, with `row` used as the value for every row. + pub fn from_row_n(row: &BitSet, num_rows: usize) -> BitMatrix { + let num_columns = row.domain_size(); + let words_per_row = num_words(num_columns); + assert_eq!(words_per_row, row.words().len()); + BitMatrix { + num_rows, + num_columns, + words: iter::repeat(row.words()).take(num_rows).flatten().cloned().collect(), + marker: PhantomData, + } + } + + pub fn rows(&self) -> impl Iterator { + (0..self.num_rows).map(R::new) + } + + /// The range of bits for a given row. + fn range(&self, row: R) -> (usize, usize) { + let words_per_row = num_words(self.num_columns); + let start = row.index() * words_per_row; + (start, start + words_per_row) + } + + /// Sets the cell at `(row, column)` to true. Put another way, insert + /// `column` to the bitset for `row`. + /// + /// Returns `true` if this changed the matrix. + pub fn insert(&mut self, row: R, column: C) -> bool { + assert!(row.index() < self.num_rows && column.index() < self.num_columns); + let (start, _) = self.range(row); + let (word_index, mask) = word_index_and_mask(column); + let words = &mut self.words[..]; + let word = words[start + word_index]; + let new_word = word | mask; + words[start + word_index] = new_word; + word != new_word + } + + /// Do the bits from `row` contain `column`? Put another way, is + /// the matrix cell at `(row, column)` true? Put yet another way, + /// if the matrix represents (transitive) reachability, can + /// `row` reach `column`? + pub fn contains(&self, row: R, column: C) -> bool { + assert!(row.index() < self.num_rows && column.index() < self.num_columns); + let (start, _) = self.range(row); + let (word_index, mask) = word_index_and_mask(column); + (self.words[start + word_index] & mask) != 0 + } + + /// Returns those indices that are true in rows `a` and `b`. This + /// is an O(n) operation where `n` is the number of elements + /// (somewhat independent from the actual size of the + /// intersection, in particular). + pub fn intersect_rows(&self, row1: R, row2: R) -> Vec { + assert!(row1.index() < self.num_rows && row2.index() < self.num_rows); + let (row1_start, row1_end) = self.range(row1); + let (row2_start, row2_end) = self.range(row2); + let mut result = Vec::with_capacity(self.num_columns); + for (base, (i, j)) in (row1_start..row1_end).zip(row2_start..row2_end).enumerate() { + let mut v = self.words[i] & self.words[j]; + for bit in 0..WORD_BITS { + if v == 0 { + break; + } + if v & 0x1 != 0 { + result.push(C::new(base * WORD_BITS + bit)); + } + v >>= 1; + } + } + result + } + + /// Adds the bits from row `read` to the bits from row `write`, and + /// returns `true` if anything changed. + /// + /// This is used when computing transitive reachability because if + /// you have an edge `write -> read`, because in that case + /// `write` can reach everything that `read` can (and + /// potentially more). + pub fn union_rows(&mut self, read: R, write: R) -> bool { + assert!(read.index() < self.num_rows && write.index() < self.num_rows); + let (read_start, read_end) = self.range(read); + let (write_start, write_end) = self.range(write); + let words = &mut self.words[..]; + let mut changed = false; + for (read_index, write_index) in (read_start..read_end).zip(write_start..write_end) { + let word = words[write_index]; + let new_word = word | words[read_index]; + words[write_index] = new_word; + changed |= word != new_word; + } + changed + } + + /// Adds the bits from `with` to the bits from row `write`, and + /// returns `true` if anything changed. + pub fn union_row_with(&mut self, with: &BitSet, write: R) -> bool { + assert!(write.index() < self.num_rows); + assert_eq!(with.domain_size(), self.num_columns); + let (write_start, write_end) = self.range(write); + let mut changed = false; + for (read_index, write_index) in (0..with.words().len()).zip(write_start..write_end) { + let word = self.words[write_index]; + let new_word = word | with.words()[read_index]; + self.words[write_index] = new_word; + changed |= word != new_word; + } + changed + } + + /// Sets every cell in `row` to true. + pub fn insert_all_into_row(&mut self, row: R) { + assert!(row.index() < self.num_rows); + let (start, end) = self.range(row); + let words = &mut self.words[..]; + for index in start..end { + words[index] = !0; + } + self.clear_excess_bits(row); + } + + /// Clear excess bits in the final word of the row. + fn clear_excess_bits(&mut self, row: R) { + let num_bits_in_final_word = self.num_columns % WORD_BITS; + if num_bits_in_final_word > 0 { + let mask = (1 << num_bits_in_final_word) - 1; + let (_, end) = self.range(row); + let final_word_idx = end - 1; + self.words[final_word_idx] &= mask; + } + } + + /// Gets a slice of the underlying words. + pub fn words(&self) -> &[Word] { + &self.words + } + + /// Iterates through all the columns set to true in a given row of + /// the matrix. + pub fn iter(&self, row: R) -> BitIter<'_, C> { + assert!(row.index() < self.num_rows); + let (start, end) = self.range(row); + BitIter { + cur: None, + iter: self.words[start..end].iter().enumerate(), + marker: PhantomData, + } + } + + /// Returns the number of elements in `row`. + pub fn count(&self, row: R) -> usize { + let (start, end) = self.range(row); + self.words[start..end].iter().map(|e| e.count_ones() as usize).sum() + } +} + +/// A fixed-column-size, variable-row-size 2D bit matrix with a moderately +/// sparse representation. +/// +/// Initially, every row has no explicit representation. If any bit within a +/// row is set, the entire row is instantiated as `Some()`. +/// Furthermore, any previously uninstantiated rows prior to it will be +/// instantiated as `None`. Those prior rows may themselves become fully +/// instantiated later on if any of their bits are set. +/// +/// `R` and `C` are index types used to identify rows and columns respectively; +/// typically newtyped `usize` wrappers, but they can also just be `usize`. +#[derive(Clone, Debug)] +pub struct SparseBitMatrix +where + R: Idx, + C: Idx, +{ + num_columns: usize, + rows: IndexVec>>, +} + +impl SparseBitMatrix { + /// Creates a new empty sparse bit matrix with no rows or columns. + pub fn new(num_columns: usize) -> Self { + Self { + num_columns, + rows: IndexVec::new(), + } + } + + fn ensure_row(&mut self, row: R) -> &mut HybridBitSet { + // Instantiate any missing rows up to and including row `row` with an + // empty HybridBitSet. + self.rows.ensure_contains_elem(row, || None); + + // Then replace row `row` with a full HybridBitSet if necessary. + let num_columns = self.num_columns; + self.rows[row].get_or_insert_with(|| HybridBitSet::new_empty(num_columns)) + } + + /// Sets the cell at `(row, column)` to true. Put another way, insert + /// `column` to the bitset for `row`. + /// + /// Returns `true` if this changed the matrix. + pub fn insert(&mut self, row: R, column: C) -> bool { + self.ensure_row(row).insert(column) + } + + /// Do the bits from `row` contain `column`? Put another way, is + /// the matrix cell at `(row, column)` true? Put yet another way, + /// if the matrix represents (transitive) reachability, can + /// `row` reach `column`? + pub fn contains(&self, row: R, column: C) -> bool { + self.row(row).map_or(false, |r| r.contains(column)) + } + + /// Adds the bits from row `read` to the bits from row `write`, and + /// returns `true` if anything changed. + /// + /// This is used when computing transitive reachability because if + /// you have an edge `write -> read`, because in that case + /// `write` can reach everything that `read` can (and + /// potentially more). + pub fn union_rows(&mut self, read: R, write: R) -> bool { + if read == write || self.row(read).is_none() { + return false; + } + + self.ensure_row(write); + if let (Some(read_row), Some(write_row)) = self.rows.pick2_mut(read, write) { + write_row.union(read_row) + } else { + unreachable!() + } + } + + /// Union a row, `from`, into the `into` row. + pub fn union_into_row(&mut self, into: R, from: &HybridBitSet) -> bool { + self.ensure_row(into).union(from) + } + + /// Insert all bits in the given row. + pub fn insert_all_into_row(&mut self, row: R) { + self.ensure_row(row).insert_all(); + } + + pub fn rows(&self) -> impl Iterator { + self.rows.indices() + } + + /// Iterates through all the columns set to true in a given row of + /// the matrix. + pub fn iter<'a>(&'a self, row: R) -> impl Iterator + 'a { + self.row(row).into_iter().flat_map(|r| r.iter()) + } + + pub fn row(&self, row: R) -> Option<&HybridBitSet> { + if let Some(Some(row)) = self.rows.get(row) { + Some(row) + } else { + None + } + } +} + +#[inline] +fn num_words(domain_size: T) -> usize { + (domain_size.index() + WORD_BITS - 1) / WORD_BITS +} + +#[inline] +fn word_index_and_mask(elem: T) -> (usize, Word) { + let elem = elem.index(); + let word_index = elem / WORD_BITS; + let mask = 1 << (elem % WORD_BITS); + (word_index, mask) +} diff --git a/src/librustc_index/bit_set/tests.rs b/src/librustc_index/bit_set/tests.rs new file mode 100644 index 00000000000..ac7913815ff --- /dev/null +++ b/src/librustc_index/bit_set/tests.rs @@ -0,0 +1,369 @@ +use super::*; + +extern crate test; +use test::Bencher; + +#[test] +fn test_new_filled() { + for i in 0..128 { + let idx_buf = BitSet::new_filled(i); + let elems: Vec = idx_buf.iter().collect(); + let expected: Vec = (0..i).collect(); + assert_eq!(elems, expected); + } +} + +#[test] +fn bitset_iter_works() { + let mut bitset: BitSet = BitSet::new_empty(100); + bitset.insert(1); + bitset.insert(10); + bitset.insert(19); + bitset.insert(62); + bitset.insert(63); + bitset.insert(64); + bitset.insert(65); + bitset.insert(66); + bitset.insert(99); + assert_eq!( + bitset.iter().collect::>(), + [1, 10, 19, 62, 63, 64, 65, 66, 99] + ); +} + +#[test] +fn bitset_iter_works_2() { + let mut bitset: BitSet = BitSet::new_empty(320); + bitset.insert(0); + bitset.insert(127); + bitset.insert(191); + bitset.insert(255); + bitset.insert(319); + assert_eq!(bitset.iter().collect::>(), [0, 127, 191, 255, 319]); +} + +#[test] +fn union_two_sets() { + let mut set1: BitSet = BitSet::new_empty(65); + let mut set2: BitSet = BitSet::new_empty(65); + assert!(set1.insert(3)); + assert!(!set1.insert(3)); + assert!(set2.insert(5)); + assert!(set2.insert(64)); + assert!(set1.union(&set2)); + assert!(!set1.union(&set2)); + assert!(set1.contains(3)); + assert!(!set1.contains(4)); + assert!(set1.contains(5)); + assert!(!set1.contains(63)); + assert!(set1.contains(64)); +} + +#[test] +fn hybrid_bitset() { + let mut sparse038: HybridBitSet = HybridBitSet::new_empty(256); + assert!(sparse038.is_empty()); + assert!(sparse038.insert(0)); + assert!(sparse038.insert(1)); + assert!(sparse038.insert(8)); + assert!(sparse038.insert(3)); + assert!(!sparse038.insert(3)); + assert!(sparse038.remove(1)); + assert!(!sparse038.is_empty()); + assert_eq!(sparse038.iter().collect::>(), [0, 3, 8]); + + for i in 0..256 { + if i == 0 || i == 3 || i == 8 { + assert!(sparse038.contains(i)); + } else { + assert!(!sparse038.contains(i)); + } + } + + let mut sparse01358 = sparse038.clone(); + assert!(sparse01358.insert(1)); + assert!(sparse01358.insert(5)); + assert_eq!(sparse01358.iter().collect::>(), [0, 1, 3, 5, 8]); + + let mut dense10 = HybridBitSet::new_empty(256); + for i in 0..10 { + assert!(dense10.insert(i)); + } + assert!(!dense10.is_empty()); + assert_eq!(dense10.iter().collect::>(), [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); + + let mut dense256 = HybridBitSet::new_empty(256); + assert!(dense256.is_empty()); + dense256.insert_all(); + assert!(!dense256.is_empty()); + for i in 0..256 { + assert!(dense256.contains(i)); + } + + assert!(sparse038.superset(&sparse038)); // sparse + sparse (self) + assert!(sparse01358.superset(&sparse038)); // sparse + sparse + assert!(dense10.superset(&sparse038)); // dense + sparse + assert!(dense10.superset(&dense10)); // dense + dense (self) + assert!(dense256.superset(&dense10)); // dense + dense + + let mut hybrid = sparse038; + assert!(!sparse01358.union(&hybrid)); // no change + assert!(hybrid.union(&sparse01358)); + assert!(hybrid.superset(&sparse01358) && sparse01358.superset(&hybrid)); + assert!(!dense10.union(&sparse01358)); + assert!(!dense256.union(&dense10)); + let mut dense = dense10; + assert!(dense.union(&dense256)); + assert!(dense.superset(&dense256) && dense256.superset(&dense)); + assert!(hybrid.union(&dense256)); + assert!(hybrid.superset(&dense256) && dense256.superset(&hybrid)); + + assert_eq!(dense256.iter().count(), 256); + let mut dense0 = dense256; + for i in 0..256 { + assert!(dense0.remove(i)); + } + assert!(!dense0.remove(0)); + assert!(dense0.is_empty()); +} + +#[test] +fn grow() { + let mut set: GrowableBitSet = GrowableBitSet::with_capacity(65); + for index in 0..65 { + assert!(set.insert(index)); + assert!(!set.insert(index)); + } + set.ensure(128); + + // Check if the bits set before growing are still set + for index in 0..65 { + assert!(set.contains(index)); + } + + // Check if the new bits are all un-set + for index in 65..128 { + assert!(!set.contains(index)); + } + + // Check that we can set all new bits without running out of bounds + for index in 65..128 { + assert!(set.insert(index)); + assert!(!set.insert(index)); + } +} + +#[test] +fn matrix_intersection() { + let mut matrix: BitMatrix = BitMatrix::new(200, 200); + + // (*) Elements reachable from both 2 and 65. + + matrix.insert(2, 3); + matrix.insert(2, 6); + matrix.insert(2, 10); // (*) + matrix.insert(2, 64); // (*) + matrix.insert(2, 65); + matrix.insert(2, 130); + matrix.insert(2, 160); // (*) + + matrix.insert(64, 133); + + matrix.insert(65, 2); + matrix.insert(65, 8); + matrix.insert(65, 10); // (*) + matrix.insert(65, 64); // (*) + matrix.insert(65, 68); + matrix.insert(65, 133); + matrix.insert(65, 160); // (*) + + let intersection = matrix.intersect_rows(2, 64); + assert!(intersection.is_empty()); + + let intersection = matrix.intersect_rows(2, 65); + assert_eq!(intersection, &[10, 64, 160]); +} + +#[test] +fn matrix_iter() { + let mut matrix: BitMatrix = BitMatrix::new(64, 100); + matrix.insert(3, 22); + matrix.insert(3, 75); + matrix.insert(2, 99); + matrix.insert(4, 0); + matrix.union_rows(3, 5); + matrix.insert_all_into_row(6); + + let expected = [99]; + let mut iter = expected.iter(); + for i in matrix.iter(2) { + let j = *iter.next().unwrap(); + assert_eq!(i, j); + } + assert!(iter.next().is_none()); + + let expected = [22, 75]; + let mut iter = expected.iter(); + assert_eq!(matrix.count(3), expected.len()); + for i in matrix.iter(3) { + let j = *iter.next().unwrap(); + assert_eq!(i, j); + } + assert!(iter.next().is_none()); + + let expected = [0]; + let mut iter = expected.iter(); + assert_eq!(matrix.count(4), expected.len()); + for i in matrix.iter(4) { + let j = *iter.next().unwrap(); + assert_eq!(i, j); + } + assert!(iter.next().is_none()); + + let expected = [22, 75]; + let mut iter = expected.iter(); + assert_eq!(matrix.count(5), expected.len()); + for i in matrix.iter(5) { + let j = *iter.next().unwrap(); + assert_eq!(i, j); + } + assert!(iter.next().is_none()); + + assert_eq!(matrix.count(6), 100); + let mut count = 0; + for (idx, i) in matrix.iter(6).enumerate() { + assert_eq!(idx, i); + count += 1; + } + assert_eq!(count, 100); + + if let Some(i) = matrix.iter(7).next() { + panic!("expected no elements in row, but contains element {:?}", i); + } +} + +#[test] +fn sparse_matrix_iter() { + let mut matrix: SparseBitMatrix = SparseBitMatrix::new(100); + matrix.insert(3, 22); + matrix.insert(3, 75); + matrix.insert(2, 99); + matrix.insert(4, 0); + matrix.union_rows(3, 5); + + let expected = [99]; + let mut iter = expected.iter(); + for i in matrix.iter(2) { + let j = *iter.next().unwrap(); + assert_eq!(i, j); + } + assert!(iter.next().is_none()); + + let expected = [22, 75]; + let mut iter = expected.iter(); + for i in matrix.iter(3) { + let j = *iter.next().unwrap(); + assert_eq!(i, j); + } + assert!(iter.next().is_none()); + + let expected = [0]; + let mut iter = expected.iter(); + for i in matrix.iter(4) { + let j = *iter.next().unwrap(); + assert_eq!(i, j); + } + assert!(iter.next().is_none()); + + let expected = [22, 75]; + let mut iter = expected.iter(); + for i in matrix.iter(5) { + let j = *iter.next().unwrap(); + assert_eq!(i, j); + } + assert!(iter.next().is_none()); +} + +/// Merge dense hybrid set into empty sparse hybrid set. +#[bench] +fn union_hybrid_sparse_empty_to_dense(b: &mut Bencher) { + let mut pre_dense: HybridBitSet = HybridBitSet::new_empty(256); + for i in 0..10 { + assert!(pre_dense.insert(i)); + } + let pre_sparse: HybridBitSet = HybridBitSet::new_empty(256); + b.iter(|| { + let dense = pre_dense.clone(); + let mut sparse = pre_sparse.clone(); + sparse.union(&dense); + }) +} + +/// Merge dense hybrid set into full hybrid set with same indices. +#[bench] +fn union_hybrid_sparse_full_to_dense(b: &mut Bencher) { + let mut pre_dense: HybridBitSet = HybridBitSet::new_empty(256); + for i in 0..10 { + assert!(pre_dense.insert(i)); + } + let mut pre_sparse: HybridBitSet = HybridBitSet::new_empty(256); + for i in 0..SPARSE_MAX { + assert!(pre_sparse.insert(i)); + } + b.iter(|| { + let dense = pre_dense.clone(); + let mut sparse = pre_sparse.clone(); + sparse.union(&dense); + }) +} + +/// Merge dense hybrid set into full hybrid set with indices over the whole domain. +#[bench] +fn union_hybrid_sparse_domain_to_dense(b: &mut Bencher) { + let mut pre_dense: HybridBitSet = HybridBitSet::new_empty(SPARSE_MAX*64); + for i in 0..10 { + assert!(pre_dense.insert(i)); + } + let mut pre_sparse: HybridBitSet = HybridBitSet::new_empty(SPARSE_MAX*64); + for i in 0..SPARSE_MAX { + assert!(pre_sparse.insert(i*64)); + } + b.iter(|| { + let dense = pre_dense.clone(); + let mut sparse = pre_sparse.clone(); + sparse.union(&dense); + }) +} + +/// Merge dense hybrid set into empty hybrid set where the domain is very small. +#[bench] +fn union_hybrid_sparse_empty_small_domain(b: &mut Bencher) { + let mut pre_dense: HybridBitSet = HybridBitSet::new_empty(SPARSE_MAX); + for i in 0..SPARSE_MAX { + assert!(pre_dense.insert(i)); + } + let pre_sparse: HybridBitSet = HybridBitSet::new_empty(SPARSE_MAX); + b.iter(|| { + let dense = pre_dense.clone(); + let mut sparse = pre_sparse.clone(); + sparse.union(&dense); + }) +} + +/// Merge dense hybrid set into full hybrid set where the domain is very small. +#[bench] +fn union_hybrid_sparse_full_small_domain(b: &mut Bencher) { + let mut pre_dense: HybridBitSet = HybridBitSet::new_empty(SPARSE_MAX); + for i in 0..SPARSE_MAX { + assert!(pre_dense.insert(i)); + } + let mut pre_sparse: HybridBitSet = HybridBitSet::new_empty(SPARSE_MAX); + for i in 0..SPARSE_MAX { + assert!(pre_sparse.insert(i)); + } + b.iter(|| { + let dense = pre_dense.clone(); + let mut sparse = pre_sparse.clone(); + sparse.union(&dense); + }) +} diff --git a/src/librustc_index/lib.rs b/src/librustc_index/lib.rs index c4c4948e7bf..d70f51aec01 100644 --- a/src/librustc_index/lib.rs +++ b/src/librustc_index/lib.rs @@ -3,3 +3,4 @@ #![feature(fn_traits)] pub mod indexed_vec; +pub mod bit_set; -- cgit 1.4.1-3-g733a5 From d20183dbbff4b59da48aedf28e1eb38f55681b58 Mon Sep 17 00:00:00 2001 From: csmoe Date: Thu, 26 Sep 2019 05:30:10 +0000 Subject: remove bit_set re-export from rustc_data_structures --- Cargo.lock | 6 ++++++ src/librustc/Cargo.toml | 1 + src/librustc/arena.rs | 2 +- src/librustc/mir/mod.rs | 2 +- src/librustc/mir/traversal.rs | 2 +- src/librustc/traits/select.rs | 2 +- src/librustc/ty/layout.rs | 2 +- src/librustc/ty/query/mod.rs | 4 ++-- src/librustc_codegen_llvm/Cargo.toml | 1 + src/librustc_codegen_llvm/debuginfo/create_scope_map.rs | 2 +- src/librustc_codegen_ssa/Cargo.toml | 1 + src/librustc_codegen_ssa/mir/analyze.rs | 2 +- src/librustc_codegen_ssa/mir/mod.rs | 2 +- src/librustc_data_structures/graph/implementation/mod.rs | 2 +- src/librustc_data_structures/graph/iterate/mod.rs | 2 +- src/librustc_data_structures/lib.rs | 2 +- src/librustc_data_structures/stable_hasher.rs | 2 +- src/librustc_data_structures/transitive_relation.rs | 2 +- src/librustc_data_structures/work_queue.rs | 2 +- src/librustc_index/lib.rs | 1 + src/librustc_metadata/Cargo.toml | 1 + src/librustc_metadata/cstore_impl.rs | 2 +- src/librustc_mir/Cargo.toml | 1 + src/librustc_mir/borrow_check/borrow_set.rs | 2 +- src/librustc_mir/borrow_check/flows.rs | 2 +- src/librustc_mir/borrow_check/mod.rs | 2 +- src/librustc_mir/borrow_check/nll/region_infer/mod.rs | 2 +- src/librustc_mir/borrow_check/nll/region_infer/values.rs | 2 +- src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs | 2 +- src/librustc_mir/build/matches/mod.rs | 2 +- src/librustc_mir/build/matches/test.rs | 4 ++-- src/librustc_mir/dataflow/at_location.rs | 2 +- src/librustc_mir/dataflow/generic.rs | 2 +- src/librustc_mir/dataflow/impls/borrows.rs | 2 +- src/librustc_mir/dataflow/impls/mod.rs | 2 +- src/librustc_mir/dataflow/mod.rs | 2 +- src/librustc_mir/lints.rs | 2 +- src/librustc_mir/monomorphize/collector.rs | 2 +- src/librustc_mir/transform/elaborate_drops.rs | 2 +- src/librustc_mir/transform/generator.rs | 2 +- src/librustc_mir/transform/inline.rs | 2 +- src/librustc_mir/transform/qualify_consts.rs | 2 +- src/librustc_mir/transform/remove_noop_landing_pads.rs | 2 +- src/librustc_mir/transform/rustc_peek.rs | 2 +- src/librustc_mir/transform/simplify.rs | 2 +- src/librustc_mir/util/liveness.rs | 2 +- src/libsyntax/Cargo.toml | 1 + src/libsyntax/lib.rs | 2 +- 48 files changed, 55 insertions(+), 42 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 59505ff7ed7..3c49d6f4d2c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3082,6 +3082,7 @@ dependencies = [ "rustc_data_structures", "rustc_errors", "rustc_fs_util", + "rustc_index", "rustc_macros", "rustc_target", "scoped-tls", @@ -3341,6 +3342,7 @@ dependencies = [ name = "rustc_codegen_llvm" version = "0.0.0" dependencies = [ + "rustc_index", "rustc_llvm", ] @@ -3362,6 +3364,7 @@ dependencies = [ "rustc_errors", "rustc_fs_util", "rustc_incremental", + "rustc_index", "rustc_target", "serialize", "syntax", @@ -3561,6 +3564,7 @@ dependencies = [ "rustc", "rustc_data_structures", "rustc_errors", + "rustc_index", "rustc_target", "serialize", "smallvec", @@ -3583,6 +3587,7 @@ dependencies = [ "rustc_apfloat", "rustc_data_structures", "rustc_errors", + "rustc_index", "rustc_lexer", "rustc_target", "serialize", @@ -4246,6 +4251,7 @@ dependencies = [ "log", "rustc_data_structures", "rustc_errors", + "rustc_index", "rustc_lexer", "rustc_target", "scoped-tls", diff --git a/src/librustc/Cargo.toml b/src/librustc/Cargo.toml index 0834faf1324..a7c94d057dc 100644 --- a/src/librustc/Cargo.toml +++ b/src/librustc/Cargo.toml @@ -25,6 +25,7 @@ rustc_apfloat = { path = "../librustc_apfloat" } rustc_target = { path = "../librustc_target" } rustc_macros = { path = "../librustc_macros" } rustc_data_structures = { path = "../librustc_data_structures" } +rustc_index = { path = "../librustc_index" } errors = { path = "../librustc_errors", package = "rustc_errors" } rustc_serialize = { path = "../libserialize", package = "serialize" } syntax = { path = "../libsyntax" } diff --git a/src/librustc/arena.rs b/src/librustc/arena.rs index 5d06f62f446..b922910c4d7 100644 --- a/src/librustc/arena.rs +++ b/src/librustc/arena.rs @@ -45,7 +45,7 @@ macro_rules! arena_types { [decode] specialization_graph: rustc::traits::specialization_graph::Graph, [] region_scope_tree: rustc::middle::region::ScopeTree, [] item_local_set: rustc::util::nodemap::ItemLocalSet, - [decode] mir_const_qualif: rustc_data_structures::bit_set::BitSet, + [decode] mir_const_qualif: rustc_index::bit_set::BitSet, [] trait_impls_of: rustc::ty::trait_def::TraitImpls, [] dropck_outlives: rustc::infer::canonical::Canonical<'tcx, diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 5e12c4dfe75..00d7400a651 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -20,7 +20,7 @@ use crate::ty::{ }; use polonius_engine::Atom; -use rustc_data_structures::bit_set::BitMatrix; +use rustc_index::bit_set::BitMatrix; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::graph::dominators::{dominators, Dominators}; use rustc_data_structures::graph::{self, GraphPredecessors, GraphSuccessors}; diff --git a/src/librustc/mir/traversal.rs b/src/librustc/mir/traversal.rs index 1416a5f0a6e..f129dd3abef 100644 --- a/src/librustc/mir/traversal.rs +++ b/src/librustc/mir/traversal.rs @@ -1,4 +1,4 @@ -use rustc_data_structures::bit_set::BitSet; +use rustc_index::bit_set::BitSet; use super::*; diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index e1ca9a16d96..ef79417c6f0 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -40,7 +40,7 @@ use crate::ty::subst::{Subst, SubstsRef}; use crate::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable}; use crate::hir; -use rustc_data_structures::bit_set::GrowableBitSet; +use rustc_index::bit_set::GrowableBitSet; use rustc_data_structures::sync::Lock; use rustc_target::spec::abi::Abi; use syntax::attr; diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index 6ab4f4c6112..eb2e1de7787 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -17,7 +17,7 @@ use crate::ich::StableHashingContext; use crate::mir::{GeneratorLayout, GeneratorSavedLocal}; use crate::ty::GeneratorSubsts; use crate::ty::subst::Subst; -use rustc_data_structures::bit_set::BitSet; +use rustc_index::bit_set::BitSet; use rustc_data_structures::indexed_vec::{IndexVec, Idx}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs index f559cde4b03..e5c3a8402a7 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -38,11 +38,11 @@ use crate::ty::steal::Steal; use crate::ty::util::NeedsDrop; use crate::ty::subst::SubstsRef; use crate::util::nodemap::{DefIdSet, DefIdMap, ItemLocalSet}; -use crate::util::common::{ErrorReported}; +use crate::util::common::ErrorReported; use crate::util::profiling::ProfileCategory::*; use rustc_data_structures::svh::Svh; -use rustc_data_structures::bit_set::BitSet; +use rustc_index::bit_set::BitSet; use rustc_data_structures::indexed_vec::IndexVec; use rustc_data_structures::fx::{FxIndexMap, FxHashMap, FxHashSet}; use rustc_data_structures::stable_hasher::StableVec; diff --git a/src/librustc_codegen_llvm/Cargo.toml b/src/librustc_codegen_llvm/Cargo.toml index 98efa6a5804..540ab2a352a 100644 --- a/src/librustc_codegen_llvm/Cargo.toml +++ b/src/librustc_codegen_llvm/Cargo.toml @@ -12,6 +12,7 @@ test = false [dependencies] rustc_llvm = { path = "../librustc_llvm" } +rustc_index = { path = "../librustc_index" } [features] # This is used to convince Cargo to separately cache builds of `rustc_codegen_llvm` diff --git a/src/librustc_codegen_llvm/debuginfo/create_scope_map.rs b/src/librustc_codegen_llvm/debuginfo/create_scope_map.rs index 8b3ed5b0c62..45af55a7be7 100644 --- a/src/librustc_codegen_llvm/debuginfo/create_scope_map.rs +++ b/src/librustc_codegen_llvm/debuginfo/create_scope_map.rs @@ -11,7 +11,7 @@ use libc::c_uint; use syntax_pos::Pos; -use rustc_data_structures::bit_set::BitSet; +use rustc_index::bit_set::BitSet; use rustc_data_structures::indexed_vec::{Idx, IndexVec}; use syntax_pos::BytePos; diff --git a/src/librustc_codegen_ssa/Cargo.toml b/src/librustc_codegen_ssa/Cargo.toml index 2e3666e6096..c7d09a423d5 100644 --- a/src/librustc_codegen_ssa/Cargo.toml +++ b/src/librustc_codegen_ssa/Cargo.toml @@ -29,4 +29,5 @@ rustc_data_structures = { path = "../librustc_data_structures"} rustc_errors = { path = "../librustc_errors" } rustc_fs_util = { path = "../librustc_fs_util" } rustc_incremental = { path = "../librustc_incremental" } +rustc_index = { path = "../librustc_index" } rustc_target = { path = "../librustc_target" } diff --git a/src/librustc_codegen_ssa/mir/analyze.rs b/src/librustc_codegen_ssa/mir/analyze.rs index 05896523863..9dc3d956aaf 100644 --- a/src/librustc_codegen_ssa/mir/analyze.rs +++ b/src/librustc_codegen_ssa/mir/analyze.rs @@ -1,7 +1,7 @@ //! An analysis to determine which locals require allocas and //! which do not. -use rustc_data_structures::bit_set::BitSet; +use rustc_index::bit_set::BitSet; use rustc_data_structures::graph::dominators::Dominators; use rustc_data_structures::indexed_vec::{Idx, IndexVec}; use rustc::mir::{self, Location, TerminatorKind}; diff --git a/src/librustc_codegen_ssa/mir/mod.rs b/src/librustc_codegen_ssa/mir/mod.rs index 4f3a8bdb540..7cf8a69cee3 100644 --- a/src/librustc_codegen_ssa/mir/mod.rs +++ b/src/librustc_codegen_ssa/mir/mod.rs @@ -13,7 +13,7 @@ use syntax::symbol::kw; use std::iter; -use rustc_data_structures::bit_set::BitSet; +use rustc_index::bit_set::BitSet; use rustc_data_structures::indexed_vec::IndexVec; use self::analyze::CleanupKind; diff --git a/src/librustc_data_structures/graph/implementation/mod.rs b/src/librustc_data_structures/graph/implementation/mod.rs index d2699004c81..052a09c0774 100644 --- a/src/librustc_data_structures/graph/implementation/mod.rs +++ b/src/librustc_data_structures/graph/implementation/mod.rs @@ -20,7 +20,7 @@ //! the field `next_edge`). Each of those fields is an array that should //! be indexed by the direction (see the type `Direction`). -use crate::bit_set::BitSet; +use rustc_index::bit_set::BitSet; use crate::snapshot_vec::{SnapshotVec, SnapshotVecDelegate}; use std::fmt::Debug; use std::usize; diff --git a/src/librustc_data_structures/graph/iterate/mod.rs b/src/librustc_data_structures/graph/iterate/mod.rs index cbf6a0a3c03..999c5df7b86 100644 --- a/src/librustc_data_structures/graph/iterate/mod.rs +++ b/src/librustc_data_structures/graph/iterate/mod.rs @@ -1,6 +1,6 @@ use super::super::indexed_vec::IndexVec; use super::{DirectedGraph, WithNumNodes, WithSuccessors, WithStartNode}; -use crate::bit_set::BitSet; +use rustc_index::bit_set::BitSet; #[cfg(test)] mod tests; diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index e28ee48201c..6a4602da36d 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -37,7 +37,7 @@ extern crate libc; extern crate cfg_if; pub use rustc_serialize::hex::ToHex; -pub use rustc_index::{bit_set, indexed_vec, newtype_index}; +pub use rustc_index::{indexed_vec, newtype_index}; #[inline(never)] #[cold] diff --git a/src/librustc_data_structures/stable_hasher.rs b/src/librustc_data_structures/stable_hasher.rs index 53dff794ff0..7f17a1aed62 100644 --- a/src/librustc_data_structures/stable_hasher.rs +++ b/src/librustc_data_structures/stable_hasher.rs @@ -3,7 +3,7 @@ use std::mem; use smallvec::SmallVec; use crate::sip128::SipHasher128; use crate::indexed_vec; -use crate::bit_set; +use rustc_index::bit_set; /// When hashing something that ends up affecting properties like symbol names, /// we want these symbol names to be calculated independently of other factors diff --git a/src/librustc_data_structures/transitive_relation.rs b/src/librustc_data_structures/transitive_relation.rs index 9c5447f3f5a..f0a9c3afc68 100644 --- a/src/librustc_data_structures/transitive_relation.rs +++ b/src/librustc_data_structures/transitive_relation.rs @@ -1,4 +1,4 @@ -use crate::bit_set::BitMatrix; +use rustc_index::bit_set::BitMatrix; use crate::fx::FxHashMap; use crate::stable_hasher::{HashStable, StableHasher}; use crate::sync::Lock; diff --git a/src/librustc_data_structures/work_queue.rs b/src/librustc_data_structures/work_queue.rs index 193025aafad..2c0e2261fee 100644 --- a/src/librustc_data_structures/work_queue.rs +++ b/src/librustc_data_structures/work_queue.rs @@ -1,4 +1,4 @@ -use crate::bit_set::BitSet; +use rustc_index::bit_set::BitSet; use crate::indexed_vec::Idx; use std::collections::VecDeque; diff --git a/src/librustc_index/lib.rs b/src/librustc_index/lib.rs index d70f51aec01..5d7e0d82e78 100644 --- a/src/librustc_index/lib.rs +++ b/src/librustc_index/lib.rs @@ -1,5 +1,6 @@ #![feature(allow_internal_unstable)] #![feature(unboxed_closures)] +#![feature(test)] #![feature(fn_traits)] pub mod indexed_vec; diff --git a/src/librustc_metadata/Cargo.toml b/src/librustc_metadata/Cargo.toml index 5ff60a9267b..032470e1400 100644 --- a/src/librustc_metadata/Cargo.toml +++ b/src/librustc_metadata/Cargo.toml @@ -18,6 +18,7 @@ rustc = { path = "../librustc" } rustc_data_structures = { path = "../librustc_data_structures" } errors = { path = "../librustc_errors", package = "rustc_errors" } rustc_target = { path = "../librustc_target" } +rustc_index = { path = "../librustc_index" } rustc_serialize = { path = "../libserialize", package = "serialize" } stable_deref_trait = "1.0.0" syntax = { path = "../libsyntax" } diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index 83182df31cf..edb6f594fdd 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -35,7 +35,7 @@ use syntax::parse::source_file_to_stream; use syntax::parse::parser::emit_unclosed_delims; use syntax::symbol::Symbol; use syntax_pos::{Span, FileName}; -use rustc_data_structures::bit_set::BitSet; +use rustc_index::bit_set::BitSet; macro_rules! provide { (<$lt:tt> $tcx:ident, $def_id:ident, $other:ident, $cdata:ident, diff --git a/src/librustc_mir/Cargo.toml b/src/librustc_mir/Cargo.toml index f296753a030..f0cdcf2136b 100644 --- a/src/librustc_mir/Cargo.toml +++ b/src/librustc_mir/Cargo.toml @@ -19,6 +19,7 @@ polonius-engine = "0.10.0" rustc = { path = "../librustc" } rustc_target = { path = "../librustc_target" } rustc_data_structures = { path = "../librustc_data_structures" } +rustc_index = { path = "../librustc_index" } rustc_errors = { path = "../librustc_errors" } rustc_lexer = { path = "../librustc_lexer" } rustc_serialize = { path = "../libserialize", package = "serialize" } diff --git a/src/librustc_mir/borrow_check/borrow_set.rs b/src/librustc_mir/borrow_check/borrow_set.rs index db19cbc3175..3dcd1f56209 100644 --- a/src/librustc_mir/borrow_check/borrow_set.rs +++ b/src/librustc_mir/borrow_check/borrow_set.rs @@ -9,7 +9,7 @@ use rustc::mir::{self, Location, Body, Local}; use rustc::ty::{RegionVid, TyCtxt}; use rustc::util::nodemap::{FxHashMap, FxHashSet}; use rustc_data_structures::indexed_vec::IndexVec; -use rustc_data_structures::bit_set::BitSet; +use rustc_index::bit_set::BitSet; use std::fmt; use std::ops::Index; diff --git a/src/librustc_mir/borrow_check/flows.rs b/src/librustc_mir/borrow_check/flows.rs index 1f17ab69f66..ce5d2a14bd1 100644 --- a/src/librustc_mir/borrow_check/flows.rs +++ b/src/librustc_mir/borrow_check/flows.rs @@ -5,7 +5,7 @@ use rustc::mir::{BasicBlock, Local, Location}; use rustc::ty::RegionVid; -use rustc_data_structures::bit_set::BitIter; +use rustc_index::bit_set::BitIter; use crate::borrow_check::location::LocationIndex; diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index cf80a1bc643..b9009ac5a51 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -18,7 +18,7 @@ use rustc::ty::query::Providers; use rustc::ty::{self, TyCtxt}; use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder}; -use rustc_data_structures::bit_set::BitSet; +use rustc_index::bit_set::BitSet; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::graph::dominators::Dominators; use rustc_data_structures::indexed_vec::IndexVec; diff --git a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs index 78e7943598d..030839cdb7e 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs @@ -27,7 +27,7 @@ use rustc::mir::{ use rustc::ty::{self, subst::SubstsRef, RegionVid, Ty, TyCtxt, TypeFoldable}; use rustc::util::common::ErrorReported; use rustc_data_structures::binary_search_util; -use rustc_data_structures::bit_set::BitSet; +use rustc_index::bit_set::BitSet; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::graph::WithSuccessors; use rustc_data_structures::graph::scc::Sccs; diff --git a/src/librustc_mir/borrow_check/nll/region_infer/values.rs b/src/librustc_mir/borrow_check/nll/region_infer/values.rs index 6f9f5707935..4a56af09d88 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/values.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/values.rs @@ -1,6 +1,6 @@ use rustc::mir::{BasicBlock, Location, Body}; use rustc::ty::{self, RegionVid}; -use rustc_data_structures::bit_set::{HybridBitSet, SparseBitMatrix}; +use rustc_index::bit_set::{HybridBitSet, SparseBitMatrix}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::indexed_vec::Idx; use rustc_data_structures::indexed_vec::IndexVec; diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs index 9b55881cb1b..36482a7b135 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs @@ -12,7 +12,7 @@ use rustc::traits::query::dropck_outlives::DropckOutlivesResult; use rustc::traits::query::type_op::outlives::DropckOutlives; use rustc::traits::query::type_op::TypeOp; use rustc::ty::{Ty, TypeFoldable}; -use rustc_data_structures::bit_set::HybridBitSet; +use rustc_index::bit_set::HybridBitSet; use rustc_data_structures::fx::FxHashMap; use std::rc::Rc; diff --git a/src/librustc_mir/build/matches/mod.rs b/src/librustc_mir/build/matches/mod.rs index 8db06aa375e..861de07c612 100644 --- a/src/librustc_mir/build/matches/mod.rs +++ b/src/librustc_mir/build/matches/mod.rs @@ -15,7 +15,7 @@ use rustc::mir::*; use rustc::middle::region; use rustc::ty::{self, CanonicalUserTypeAnnotation, Ty}; use rustc::ty::layout::VariantIdx; -use rustc_data_structures::bit_set::BitSet; +use rustc_index::bit_set::BitSet; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use syntax::ast::Name; use syntax_pos::Span; diff --git a/src/librustc_mir/build/matches/test.rs b/src/librustc_mir/build/matches/test.rs index d8bb0b4f6cc..a04c989e6e0 100644 --- a/src/librustc_mir/build/matches/test.rs +++ b/src/librustc_mir/build/matches/test.rs @@ -9,9 +9,9 @@ use crate::build::Builder; use crate::build::matches::{Candidate, MatchPair, Test, TestKind}; use crate::hair::*; use crate::hair::pattern::compare_const_vals; -use rustc_data_structures::bit_set::BitSet; +use rustc_index::bit_set::BitSet; use rustc_data_structures::fx::FxHashMap; -use rustc::ty::{self, Ty, adjustment::{PointerCast}}; +use rustc::ty::{self, Ty, adjustment::PointerCast}; use rustc::ty::util::IntTypeExt; use rustc::ty::layout::VariantIdx; use rustc::mir::*; diff --git a/src/librustc_mir/dataflow/at_location.rs b/src/librustc_mir/dataflow/at_location.rs index f0014602e2d..e0ca1053523 100644 --- a/src/librustc_mir/dataflow/at_location.rs +++ b/src/librustc_mir/dataflow/at_location.rs @@ -2,7 +2,7 @@ //! locations. use rustc::mir::{BasicBlock, Location}; -use rustc_data_structures::bit_set::{BitIter, BitSet, HybridBitSet}; +use rustc_index::bit_set::{BitIter, BitSet, HybridBitSet}; use crate::dataflow::{BitDenotation, DataflowResults, GenKillSet}; use crate::dataflow::move_paths::{HasMoveData, MovePathIndex}; diff --git a/src/librustc_mir/dataflow/generic.rs b/src/librustc_mir/dataflow/generic.rs index 886044c0692..10d0627a9fb 100644 --- a/src/librustc_mir/dataflow/generic.rs +++ b/src/librustc_mir/dataflow/generic.rs @@ -20,7 +20,7 @@ use std::cmp::Ordering; use std::ops; use rustc::mir::{self, traversal, BasicBlock, Location}; -use rustc_data_structures::bit_set::BitSet; +use rustc_index::bit_set::BitSet; use rustc_data_structures::indexed_vec::{Idx, IndexVec}; use rustc_data_structures::work_queue::WorkQueue; diff --git a/src/librustc_mir/dataflow/impls/borrows.rs b/src/librustc_mir/dataflow/impls/borrows.rs index a86fcb30f4d..44f6c263fed 100644 --- a/src/librustc_mir/dataflow/impls/borrows.rs +++ b/src/librustc_mir/dataflow/impls/borrows.rs @@ -5,7 +5,7 @@ use rustc::mir::{self, Location, Place, PlaceBase, Body}; use rustc::ty::{self, TyCtxt}; use rustc::ty::RegionVid; -use rustc_data_structures::bit_set::BitSet; +use rustc_index::bit_set::BitSet; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::indexed_vec::{Idx, IndexVec}; diff --git a/src/librustc_mir/dataflow/impls/mod.rs b/src/librustc_mir/dataflow/impls/mod.rs index d669c786c09..ee33e9d47ab 100644 --- a/src/librustc_mir/dataflow/impls/mod.rs +++ b/src/librustc_mir/dataflow/impls/mod.rs @@ -4,7 +4,7 @@ use rustc::ty::TyCtxt; use rustc::mir::{self, Body, Location}; -use rustc_data_structures::bit_set::BitSet; +use rustc_index::bit_set::BitSet; use rustc_data_structures::indexed_vec::Idx; use super::MoveDataParamEnv; diff --git a/src/librustc_mir/dataflow/mod.rs b/src/librustc_mir/dataflow/mod.rs index 47eb47cf664..09362e31795 100644 --- a/src/librustc_mir/dataflow/mod.rs +++ b/src/librustc_mir/dataflow/mod.rs @@ -1,7 +1,7 @@ use syntax::ast::{self, MetaItem}; use syntax::symbol::{Symbol, sym}; -use rustc_data_structures::bit_set::{BitSet, HybridBitSet}; +use rustc_index::bit_set::{BitSet, HybridBitSet}; use rustc_data_structures::indexed_vec::Idx; use rustc_data_structures::work_queue::WorkQueue; diff --git a/src/librustc_mir/lints.rs b/src/librustc_mir/lints.rs index 4f978051eac..da3fead1f9d 100644 --- a/src/librustc_mir/lints.rs +++ b/src/librustc_mir/lints.rs @@ -1,4 +1,4 @@ -use rustc_data_structures::bit_set::BitSet; +use rustc_index::bit_set::BitSet; use rustc::hir::def_id::DefId; use rustc::hir::intravisit::FnKind; use rustc::hir::map::blocks::FnLikeNode; diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index cc8f4759e18..9c58e2aa16c 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -194,7 +194,7 @@ use crate::monomorphize; use rustc::util::nodemap::{FxHashSet, FxHashMap, DefIdMap}; use rustc::util::common::time; -use rustc_data_structures::bit_set::GrowableBitSet; +use rustc_index::bit_set::GrowableBitSet; use rustc_data_structures::sync::{MTRef, MTLock, ParallelIterator, par_iter}; use std::iter; diff --git a/src/librustc_mir/transform/elaborate_drops.rs b/src/librustc_mir/transform/elaborate_drops.rs index d7b6810a865..f91a08bcd9a 100644 --- a/src/librustc_mir/transform/elaborate_drops.rs +++ b/src/librustc_mir/transform/elaborate_drops.rs @@ -14,7 +14,7 @@ use rustc::ty::layout::VariantIdx; use rustc::hir; use rustc::mir::*; use rustc::util::nodemap::FxHashMap; -use rustc_data_structures::bit_set::BitSet; +use rustc_index::bit_set::BitSet; use std::fmt; use syntax_pos::Span; diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs index 2b66e602370..649665b4aba 100644 --- a/src/librustc_mir/transform/generator.rs +++ b/src/librustc_mir/transform/generator.rs @@ -59,7 +59,7 @@ use rustc::ty::layout::VariantIdx; use rustc::ty::subst::SubstsRef; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::indexed_vec::{Idx, IndexVec}; -use rustc_data_structures::bit_set::{BitSet, BitMatrix}; +use rustc_index::bit_set::{BitSet, BitMatrix}; use std::borrow::Cow; use std::iter; use std::mem; diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs index 7f56c6f7986..f4c522245f7 100644 --- a/src/librustc_mir/transform/inline.rs +++ b/src/librustc_mir/transform/inline.rs @@ -3,7 +3,7 @@ use rustc::hir::CodegenFnAttrFlags; use rustc::hir::def_id::DefId; -use rustc_data_structures::bit_set::BitSet; +use rustc_index::bit_set::BitSet; use rustc_data_structures::indexed_vec::{Idx, IndexVec}; use rustc::mir::*; diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 387540655f0..ee7b0cada12 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -4,7 +4,7 @@ //! The Qualif flags below can be used to also provide better //! diagnostics as to why a constant rvalue wasn't promoted. -use rustc_data_structures::bit_set::BitSet; +use rustc_index::bit_set::BitSet; use rustc_data_structures::indexed_vec::IndexVec; use rustc_data_structures::fx::FxHashSet; use rustc_target::spec::abi::Abi; diff --git a/src/librustc_mir/transform/remove_noop_landing_pads.rs b/src/librustc_mir/transform/remove_noop_landing_pads.rs index 70b11944e2f..e1994c5f639 100644 --- a/src/librustc_mir/transform/remove_noop_landing_pads.rs +++ b/src/librustc_mir/transform/remove_noop_landing_pads.rs @@ -1,6 +1,6 @@ use rustc::ty::TyCtxt; use rustc::mir::*; -use rustc_data_structures::bit_set::BitSet; +use rustc_index::bit_set::BitSet; use crate::transform::{MirPass, MirSource}; use crate::util::patch::MirPatch; diff --git a/src/librustc_mir/transform/rustc_peek.rs b/src/librustc_mir/transform/rustc_peek.rs index 539645d0227..f509d2d7104 100644 --- a/src/librustc_mir/transform/rustc_peek.rs +++ b/src/librustc_mir/transform/rustc_peek.rs @@ -6,7 +6,7 @@ use syntax_pos::Span; use rustc::ty::{self, TyCtxt}; use rustc::hir::def_id::DefId; use rustc::mir::{self, Body, Location}; -use rustc_data_structures::bit_set::BitSet; +use rustc_index::bit_set::BitSet; use crate::transform::{MirPass, MirSource}; use crate::dataflow::{do_dataflow, DebugFormatted}; diff --git a/src/librustc_mir/transform/simplify.rs b/src/librustc_mir/transform/simplify.rs index d4599ee08aa..c6df9d49ec0 100644 --- a/src/librustc_mir/transform/simplify.rs +++ b/src/librustc_mir/transform/simplify.rs @@ -27,7 +27,7 @@ //! naively generate still contains the `_a = ()` write in the unreachable block "after" the //! return. -use rustc_data_structures::bit_set::BitSet; +use rustc_index::bit_set::BitSet; use rustc_data_structures::indexed_vec::{Idx, IndexVec}; use rustc::ty::TyCtxt; use rustc::mir::*; diff --git a/src/librustc_mir/util/liveness.rs b/src/librustc_mir/util/liveness.rs index b42eebc7ee3..24ee803c9f8 100644 --- a/src/librustc_mir/util/liveness.rs +++ b/src/librustc_mir/util/liveness.rs @@ -30,7 +30,7 @@ use rustc::mir::visit::{ use rustc::mir::Local; use rustc::mir::*; use rustc::ty::{self, TyCtxt}; -use rustc_data_structures::bit_set::BitSet; +use rustc_index::bit_set::BitSet; use rustc_data_structures::indexed_vec::{Idx, IndexVec}; use rustc_data_structures::work_queue::WorkQueue; use std::fs; diff --git a/src/libsyntax/Cargo.toml b/src/libsyntax/Cargo.toml index 196cf4d9dfa..d8de21cc677 100644 --- a/src/libsyntax/Cargo.toml +++ b/src/libsyntax/Cargo.toml @@ -18,6 +18,7 @@ lazy_static = "1.0.0" syntax_pos = { path = "../libsyntax_pos" } errors = { path = "../librustc_errors", package = "rustc_errors" } rustc_data_structures = { path = "../librustc_data_structures" } +rustc_index = { path = "../librustc_index" } rustc_lexer = { path = "../librustc_lexer" } rustc_target = { path = "../librustc_target" } smallvec = { version = "0.6.7", features = ["union", "may_dangle"] } diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 2c10220c766..d2c76b669dd 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -26,7 +26,7 @@ extern crate proc_macro; pub use errors; use rustc_data_structures::sync::Lock; -use rustc_data_structures::bit_set::GrowableBitSet; +use rustc_index::bit_set::GrowableBitSet; pub use rustc_data_structures::thin_vec::ThinVec; use ast::AttrId; use syntax_pos::edition::Edition; -- cgit 1.4.1-3-g733a5 From 64f61c7888c9cb2cbd7d37f87a6cbec2858ee409 Mon Sep 17 00:00:00 2001 From: csmoe Date: Thu, 26 Sep 2019 05:38:33 +0000 Subject: remove indexed_vec re-export from rustc_data_structures --- Cargo.lock | 5 +- src/librustc/arena.rs | 4 +- src/librustc/dep_graph/graph.rs | 4 +- src/librustc/dep_graph/serialized.rs | 4 +- src/librustc/hir/def_id.rs | 6 +- src/librustc/hir/lowering.rs | 2 +- src/librustc/hir/map/collector.rs | 2 +- src/librustc/hir/map/definitions.rs | 2 +- src/librustc/hir/map/mod.rs | 2 +- src/librustc/hir/mod.rs | 4 +- src/librustc/infer/canonical/canonicalizer.rs | 2 +- src/librustc/infer/canonical/mod.rs | 2 +- src/librustc/infer/canonical/query_response.rs | 4 +- src/librustc/infer/lexical_region_resolve/mod.rs | 2 +- src/librustc/infer/region_constraints/mod.rs | 2 +- src/librustc/middle/intrinsicck.rs | 2 +- src/librustc/middle/region.rs | 4 +- src/librustc/mir/cache.rs | 2 +- src/librustc/mir/mod.rs | 14 +- src/librustc/query/mod.rs | 2 +- src/librustc/ty/context.rs | 4 +- src/librustc/ty/layout.rs | 2 +- src/librustc/ty/mod.rs | 4 +- src/librustc/ty/query/mod.rs | 2 +- src/librustc/ty/query/on_disk_cache.rs | 2 +- src/librustc/ty/structural_impls.rs | 2 +- src/librustc/ty/sty.rs | 8 +- src/librustc_codegen_llvm/Cargo.toml | 1 - .../debuginfo/create_scope_map.rs | 2 +- src/librustc_codegen_llvm/debuginfo/mod.rs | 2 +- src/librustc_codegen_llvm/lib.rs | 1 + src/librustc_codegen_ssa/back/symbol_export.rs | 2 +- src/librustc_codegen_ssa/base.rs | 2 +- src/librustc_codegen_ssa/mir/analyze.rs | 2 +- src/librustc_codegen_ssa/mir/block.rs | 2 +- src/librustc_codegen_ssa/mir/constant.rs | 2 +- src/librustc_codegen_ssa/mir/mod.rs | 2 +- src/librustc_codegen_ssa/traits/debuginfo.rs | 2 +- .../graph/dominators/mod.rs | 2 +- src/librustc_data_structures/graph/iterate/mod.rs | 2 +- src/librustc_data_structures/graph/mod.rs | 2 +- src/librustc_data_structures/graph/scc/mod.rs | 2 +- .../graph/vec_graph/mod.rs | 2 +- src/librustc_data_structures/lib.rs | 1 - .../obligation_forest/mod.rs | 2 +- src/librustc_data_structures/stable_hasher.rs | 8 +- src/librustc_data_structures/vec_linked_list.rs | 2 +- src/librustc_data_structures/work_queue.rs | 2 +- src/librustc_index/bit_set.rs | 2 +- src/librustc_index/indexed_vec.rs | 830 --------------------- src/librustc_index/lib.rs | 2 +- src/librustc_index/vec.rs | 830 +++++++++++++++++++++ src/librustc_lint/Cargo.toml | 1 + src/librustc_lint/types.rs | 2 +- src/librustc_metadata/cstore.rs | 2 +- src/librustc_metadata/decoder.rs | 2 +- src/librustc_metadata/encoder.rs | 2 +- src/librustc_metadata/schema.rs | 2 +- src/librustc_mir/borrow_check/borrow_set.rs | 2 +- src/librustc_mir/borrow_check/conflict_errors.rs | 2 +- src/librustc_mir/borrow_check/location.rs | 4 +- src/librustc_mir/borrow_check/mod.rs | 2 +- src/librustc_mir/borrow_check/mutability_errors.rs | 2 +- .../borrow_check/nll/constraints/graph.rs | 2 +- .../borrow_check/nll/constraints/mod.rs | 6 +- src/librustc_mir/borrow_check/nll/facts.rs | 2 +- .../borrow_check/nll/member_constraints.rs | 4 +- src/librustc_mir/borrow_check/nll/mod.rs | 2 +- .../nll/region_infer/error_reporting/mod.rs | 2 +- .../nll/region_infer/error_reporting/var_name.rs | 2 +- .../borrow_check/nll/region_infer/mod.rs | 2 +- .../borrow_check/nll/region_infer/values.rs | 8 +- src/librustc_mir/borrow_check/nll/renumber.rs | 2 +- .../borrow_check/nll/type_check/input_output.rs | 2 +- .../nll/type_check/liveness/local_use_map.rs | 4 +- .../borrow_check/nll/type_check/mod.rs | 2 +- .../borrow_check/nll/universal_regions.rs | 2 +- src/librustc_mir/build/expr/as_place.rs | 2 +- src/librustc_mir/build/expr/as_rvalue.rs | 2 +- src/librustc_mir/build/mod.rs | 4 +- src/librustc_mir/dataflow/generic.rs | 2 +- src/librustc_mir/dataflow/impls/borrows.rs | 4 +- .../dataflow/impls/indirect_mutation.rs | 2 +- src/librustc_mir/dataflow/impls/mod.rs | 2 +- src/librustc_mir/dataflow/mod.rs | 2 +- src/librustc_mir/dataflow/move_paths/builder.rs | 2 +- src/librustc_mir/dataflow/move_paths/mod.rs | 8 +- src/librustc_mir/hair/cx/block.rs | 2 +- src/librustc_mir/hair/cx/expr.rs | 2 +- src/librustc_mir/hair/cx/mod.rs | 2 +- src/librustc_mir/hair/pattern/_match.rs | 2 +- src/librustc_mir/hair/pattern/mod.rs | 2 +- src/librustc_mir/interpret/eval_context.rs | 2 +- src/librustc_mir/interpret/snapshot.rs | 2 +- src/librustc_mir/shim.rs | 2 +- src/librustc_mir/transform/add_call_guards.rs | 2 +- src/librustc_mir/transform/check_consts/qualifs.rs | 2 +- .../transform/check_consts/resolver.rs | 2 +- .../transform/check_consts/validation.rs | 2 +- src/librustc_mir/transform/check_unsafety.rs | 2 +- src/librustc_mir/transform/const_prop.rs | 2 +- src/librustc_mir/transform/generator.rs | 2 +- src/librustc_mir/transform/inline.rs | 2 +- src/librustc_mir/transform/instcombine.rs | 2 +- src/librustc_mir/transform/mod.rs | 2 +- src/librustc_mir/transform/promote_consts.rs | 2 +- src/librustc_mir/transform/qualify_consts.rs | 2 +- src/librustc_mir/transform/simplify.rs | 2 +- .../transform/uniform_array_move_out.rs | 2 +- src/librustc_mir/util/aggregate.rs | 2 +- src/librustc_mir/util/def_use.rs | 2 +- src/librustc_mir/util/elaborate_drops.rs | 2 +- src/librustc_mir/util/graphviz.rs | 2 +- src/librustc_mir/util/liveness.rs | 2 +- src/librustc_mir/util/patch.rs | 2 +- src/librustc_mir/util/pretty.rs | 2 +- src/librustc_target/Cargo.toml | 1 + src/librustc_target/abi/mod.rs | 5 +- src/librustc_typeck/Cargo.toml | 1 + src/librustc_typeck/check/mod.rs | 2 +- src/librustdoc/clean/mod.rs | 2 +- src/librustdoc/lib.rs | 1 + src/libsyntax/ast.rs | 7 +- src/libsyntax_pos/Cargo.toml | 1 + src/libsyntax_pos/symbol.rs | 11 +- src/test/ui-fulldeps/newtype_index.rs | 4 +- 126 files changed, 998 insertions(+), 994 deletions(-) delete mode 100644 src/librustc_index/indexed_vec.rs create mode 100644 src/librustc_index/vec.rs diff --git a/Cargo.lock b/Cargo.lock index 3c49d6f4d2c..97e8e715c1b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3342,7 +3342,6 @@ dependencies = [ name = "rustc_codegen_llvm" version = "0.0.0" dependencies = [ - "rustc_index", "rustc_llvm", ] @@ -3519,6 +3518,7 @@ dependencies = [ "log", "rustc", "rustc_data_structures", + "rustc_index", "rustc_target", "syntax", "syntax_pos", @@ -3687,6 +3687,7 @@ dependencies = [ "bitflags", "log", "rustc_data_structures", + "rustc_index", "serialize", "syntax_pos", ] @@ -3735,6 +3736,7 @@ dependencies = [ "rustc", "rustc_data_structures", "rustc_errors", + "rustc_index", "rustc_target", "smallvec", "syntax", @@ -4281,6 +4283,7 @@ dependencies = [ "arena", "cfg-if", "rustc_data_structures", + "rustc_index", "rustc_macros", "scoped-tls", "serialize", diff --git a/src/librustc/arena.rs b/src/librustc/arena.rs index b922910c4d7..5a5919d7866 100644 --- a/src/librustc/arena.rs +++ b/src/librustc/arena.rs @@ -26,12 +26,12 @@ macro_rules! arena_types { [] steal_mir: rustc::ty::steal::Steal>, [] mir: rustc::mir::Body<$tcx>, [] steal_promoted: rustc::ty::steal::Steal< - rustc_data_structures::indexed_vec::IndexVec< + rustc_index::vec::IndexVec< rustc::mir::Promoted, rustc::mir::Body<$tcx> > >, - [] promoted: rustc_data_structures::indexed_vec::IndexVec< + [] promoted: rustc_index::vec::IndexVec< rustc::mir::Promoted, rustc::mir::Body<$tcx> >, diff --git a/src/librustc/dep_graph/graph.rs b/src/librustc/dep_graph/graph.rs index acfdc91523f..0c56fc7914b 100644 --- a/src/librustc/dep_graph/graph.rs +++ b/src/librustc/dep_graph/graph.rs @@ -1,7 +1,7 @@ use errors::Diagnostic; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_data_structures::indexed_vec::{Idx, IndexVec}; +use rustc_index::vec::{Idx, IndexVec}; use smallvec::SmallVec; use rustc_data_structures::sync::{Lrc, Lock, AtomicU32, Ordering}; use std::env; @@ -26,7 +26,7 @@ pub struct DepGraph { data: Option>, } -newtype_index! { +rustc_index::newtype_index! { pub struct DepNodeIndex { .. } } diff --git a/src/librustc/dep_graph/serialized.rs b/src/librustc/dep_graph/serialized.rs index b64f71ed908..4302195755e 100644 --- a/src/librustc/dep_graph/serialized.rs +++ b/src/librustc/dep_graph/serialized.rs @@ -2,9 +2,9 @@ use crate::dep_graph::DepNode; use crate::ich::Fingerprint; -use rustc_data_structures::indexed_vec::{IndexVec, Idx}; +use rustc_index::vec::{IndexVec, Idx}; -newtype_index! { +rustc_index::newtype_index! { pub struct SerializedDepNodeIndex { .. } } diff --git a/src/librustc/hir/def_id.rs b/src/librustc/hir/def_id.rs index d0bdc149131..13200b38f2c 100644 --- a/src/librustc/hir/def_id.rs +++ b/src/librustc/hir/def_id.rs @@ -1,9 +1,9 @@ use crate::ty::{self, TyCtxt}; -use rustc_data_structures::indexed_vec::Idx; +use rustc_index::vec::Idx; use std::fmt; use std::u32; -newtype_index! { +rustc_index::newtype_index! { pub struct CrateId { ENCODABLE = custom } @@ -87,7 +87,7 @@ impl fmt::Display for CrateNum { impl rustc_serialize::UseSpecializedEncodable for CrateNum {} impl rustc_serialize::UseSpecializedDecodable for CrateNum {} -newtype_index! { +rustc_index::newtype_index! { /// A DefIndex is an index into the hir-map for a crate, identifying a /// particular definition. It should really be considered an interned /// shorthand for a particular DefPath. diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 6f51e05881b..4310bafd781 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -52,7 +52,7 @@ use crate::util::common::FN_OUTPUT_NAME; use crate::util::nodemap::{DefIdMap, NodeMap}; use errors::Applicability; use rustc_data_structures::fx::FxHashSet; -use rustc_data_structures::indexed_vec::IndexVec; +use rustc_index::vec::IndexVec; use rustc_data_structures::thin_vec::ThinVec; use rustc_data_structures::sync::Lrc; diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs index 540d456daf3..1a970c7a2c1 100644 --- a/src/librustc/hir/map/collector.rs +++ b/src/librustc/hir/map/collector.rs @@ -5,7 +5,7 @@ use crate::hir::map::HirEntryMap; use crate::hir::def_id::{LOCAL_CRATE, CrateNum}; use crate::hir::intravisit::{Visitor, NestedVisitorMap}; use rustc_data_structures::svh::Svh; -use rustc_data_structures::indexed_vec::IndexVec; +use rustc_index::vec::IndexVec; use crate::ich::Fingerprint; use crate::middle::cstore::CrateStore; use crate::session::CrateDisambiguator; diff --git a/src/librustc/hir/map/definitions.rs b/src/librustc/hir/map/definitions.rs index 187bc593324..71bf230e37d 100644 --- a/src/librustc/hir/map/definitions.rs +++ b/src/librustc/hir/map/definitions.rs @@ -11,7 +11,7 @@ use crate::session::CrateDisambiguator; use crate::util::nodemap::NodeMap; use rustc_data_structures::fx::FxHashMap; -use rustc_data_structures::indexed_vec::{IndexVec}; +use rustc_index::vec::{IndexVec}; use rustc_data_structures::stable_hasher::StableHasher; use std::borrow::Borrow; use std::fmt::Write; diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 42a4a9909f8..14c04762042 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -17,7 +17,7 @@ use crate::util::common::time; use rustc_target::spec::abi::Abi; use rustc_data_structures::svh::Svh; -use rustc_data_structures::indexed_vec::IndexVec; +use rustc_index::vec::IndexVec; use syntax::ast::{self, Name, NodeId}; use syntax::source_map::Spanned; use syntax::ext::base::MacroKind; diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 4e8b4337cc6..9ae661f0952 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -122,9 +122,9 @@ impl fmt::Display for HirId { // Hack to ensure that we don't try to access the private parts of `ItemLocalId` in this module. mod item_local_id_inner { - use rustc_data_structures::indexed_vec::Idx; + use rustc_index::vec::Idx; use rustc_macros::HashStable; - newtype_index! { + rustc_index::newtype_index! { /// An `ItemLocalId` uniquely identifies something within a given "item-like"; /// that is, within a `hir::Item`, `hir::TraitItem`, or `hir::ImplItem`. There is no /// guarantee that the numerical value of a given `ItemLocalId` corresponds to diff --git a/src/librustc/infer/canonical/canonicalizer.rs b/src/librustc/infer/canonical/canonicalizer.rs index 2ea1317a94f..b9474f869ee 100644 --- a/src/librustc/infer/canonical/canonicalizer.rs +++ b/src/librustc/infer/canonical/canonicalizer.rs @@ -18,7 +18,7 @@ use crate::ty::{self, BoundVar, InferConst, List, Ty, TyCtxt, TypeFlags}; use crate::ty::flags::FlagComputation; use rustc_data_structures::fx::FxHashMap; -use rustc_data_structures::indexed_vec::Idx; +use rustc_index::vec::Idx; use smallvec::SmallVec; impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { diff --git a/src/librustc/infer/canonical/mod.rs b/src/librustc/infer/canonical/mod.rs index 4e442608f0e..562a463ded8 100644 --- a/src/librustc/infer/canonical/mod.rs +++ b/src/librustc/infer/canonical/mod.rs @@ -25,7 +25,7 @@ use crate::infer::{InferCtxt, RegionVariableOrigin, TypeVariableOrigin, TypeVari use crate::infer::{ConstVariableOrigin, ConstVariableOriginKind}; use crate::infer::region_constraints::MemberConstraint; use crate::mir::interpret::ConstValue; -use rustc_data_structures::indexed_vec::IndexVec; +use rustc_index::vec::IndexVec; use rustc_macros::HashStable; use rustc_serialize::UseSpecializedDecodable; use smallvec::SmallVec; diff --git a/src/librustc/infer/canonical/query_response.rs b/src/librustc/infer/canonical/query_response.rs index 18c1b41d5bb..95b6a8bc843 100644 --- a/src/librustc/infer/canonical/query_response.rs +++ b/src/librustc/infer/canonical/query_response.rs @@ -17,8 +17,8 @@ use crate::infer::region_constraints::{Constraint, RegionConstraintData}; use crate::infer::InferCtxtBuilder; use crate::infer::{InferCtxt, InferOk, InferResult}; use crate::mir::interpret::ConstValue; -use rustc_data_structures::indexed_vec::Idx; -use rustc_data_structures::indexed_vec::IndexVec; +use rustc_index::vec::Idx; +use rustc_index::vec::IndexVec; use std::fmt::Debug; use syntax_pos::DUMMY_SP; use crate::traits::query::{Fallible, NoSolution}; diff --git a/src/librustc/infer/lexical_region_resolve/mod.rs b/src/librustc/infer/lexical_region_resolve/mod.rs index 6282fde59ca..f11f94c428e 100644 --- a/src/librustc/infer/lexical_region_resolve/mod.rs +++ b/src/librustc/infer/lexical_region_resolve/mod.rs @@ -19,7 +19,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::graph::implementation::{ Direction, Graph, NodeIndex, INCOMING, OUTGOING, }; -use rustc_data_structures::indexed_vec::{Idx, IndexVec}; +use rustc_index::vec::{Idx, IndexVec}; use smallvec::SmallVec; use std::fmt; use syntax_pos::Span; diff --git a/src/librustc/infer/region_constraints/mod.rs b/src/librustc/infer/region_constraints/mod.rs index 21904edb309..b4b4d1fe3e1 100644 --- a/src/librustc/infer/region_constraints/mod.rs +++ b/src/librustc/infer/region_constraints/mod.rs @@ -7,7 +7,7 @@ use super::unify_key; use super::{MiscVariable, RegionVariableOrigin, SubregionOrigin}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_data_structures::indexed_vec::IndexVec; +use rustc_index::vec::IndexVec; use rustc_data_structures::sync::Lrc; use rustc_data_structures::unify as ut; use crate::hir::def_id::DefId; diff --git a/src/librustc/middle/intrinsicck.rs b/src/librustc/middle/intrinsicck.rs index c1435551a59..7b5aea8ac98 100644 --- a/src/librustc/middle/intrinsicck.rs +++ b/src/librustc/middle/intrinsicck.rs @@ -5,7 +5,7 @@ use crate::ty::layout::{LayoutError, Pointer, SizeSkeleton, VariantIdx}; use crate::ty::query::Providers; use rustc_target::spec::abi::Abi::RustIntrinsic; -use rustc_data_structures::indexed_vec::Idx; +use rustc_index::vec::Idx; use syntax_pos::{Span, sym}; use crate::hir::intravisit::{self, Visitor, NestedVisitorMap}; use crate::hir; diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index 05e4d11c3f9..9ff205228a5 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -16,8 +16,8 @@ use crate::util::nodemap::{FxHashMap, FxHashSet}; use crate::ty::{self, DefIdTree, TyCtxt}; use crate::ty::query::Providers; -use rustc_data_structures::indexed_vec::Idx; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +use rustc_index::vec::Idx; use rustc_macros::HashStable; use syntax::source_map; use syntax_pos::{Span, DUMMY_SP}; @@ -131,7 +131,7 @@ pub enum ScopeData { Remainder(FirstStatementIndex) } -newtype_index! { +rustc_index::newtype_index! { /// Represents a subscope of `block` for a binding that is introduced /// by `block.stmts[first_statement_index]`. Such subscopes represent /// a suffix of the block. Note that each subscope does not include diff --git a/src/librustc/mir/cache.rs b/src/librustc/mir/cache.rs index d8d3383903d..9b413667418 100644 --- a/src/librustc/mir/cache.rs +++ b/src/librustc/mir/cache.rs @@ -1,4 +1,4 @@ -use rustc_data_structures::indexed_vec::IndexVec; +use rustc_index::vec::IndexVec; use rustc_data_structures::sync::{RwLock, MappedReadGuard, ReadGuard}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_serialize::{Encodable, Encoder, Decodable, Decoder}; diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 00d7400a651..6664e16895a 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -24,7 +24,7 @@ use rustc_index::bit_set::BitMatrix; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::graph::dominators::{dominators, Dominators}; use rustc_data_structures::graph::{self, GraphPredecessors, GraphSuccessors}; -use rustc_data_structures::indexed_vec::{Idx, IndexVec}; +use rustc_index::vec::{Idx, IndexVec}; use rustc_data_structures::sync::Lrc; use rustc_data_structures::sync::MappedReadGuard; use rustc_macros::HashStable; @@ -581,7 +581,7 @@ impl BorrowKind { /////////////////////////////////////////////////////////////////////////// // Variables and temps -newtype_index! { +rustc_index::newtype_index! { pub struct Local { derive [HashStable] DEBUG_FORMAT = "_{}", @@ -994,7 +994,7 @@ pub struct UpvarDebuginfo { /////////////////////////////////////////////////////////////////////////// // BasicBlock -newtype_index! { +rustc_index::newtype_index! { pub struct BasicBlock { derive [HashStable] DEBUG_FORMAT = "bb{}", @@ -1832,7 +1832,7 @@ static_assert_size!(PlaceElem<'_>, 16); /// need neither the `V` parameter for `Index` nor the `T` for `Field`. pub type ProjectionKind = ProjectionElem<(), ()>; -newtype_index! { +rustc_index::newtype_index! { pub struct Field { derive [HashStable] DEBUG_FORMAT = "field[{}]" @@ -2047,7 +2047,7 @@ impl Debug for PlaceBase<'_> { /////////////////////////////////////////////////////////////////////////// // Scopes -newtype_index! { +rustc_index::newtype_index! { pub struct SourceScope { derive [HashStable] DEBUG_FORMAT = "scope[{}]", @@ -2586,7 +2586,7 @@ impl<'tcx> TypeFoldable<'tcx> for UserTypeProjection { } } -newtype_index! { +rustc_index::newtype_index! { pub struct Promoted { derive [HashStable] DEBUG_FORMAT = "promoted[{}]" @@ -2743,7 +2743,7 @@ pub struct UnsafetyCheckResult { pub unsafe_blocks: Lrc<[(hir::HirId, bool)]>, } -newtype_index! { +rustc_index::newtype_index! { pub struct GeneratorSavedLocal { derive [HashStable] DEBUG_FORMAT = "_{}", diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs index 4b1558592ae..e463810b7af 100644 --- a/src/librustc/query/mod.rs +++ b/src/librustc/query/mod.rs @@ -132,7 +132,7 @@ rustc_queries! { cache_on_disk_if { key.is_local() } load_cached(tcx, id) { let promoted: Option< - rustc_data_structures::indexed_vec::IndexVec< + rustc_index::vec::IndexVec< crate::mir::Promoted, crate::mir::Body<'tcx> >> = tcx.queries.on_disk_cache.try_load_query_result(tcx, id); diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 6c5d9a6dfdf..34c650b06a5 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -52,7 +52,7 @@ use smallvec::SmallVec; use rustc_data_structures::stable_hasher::{ HashStable, StableHasher, StableVec, hash_stable_hashmap, }; -use rustc_data_structures::indexed_vec::{Idx, IndexVec}; +use rustc_index::vec::{Idx, IndexVec}; use rustc_data_structures::sharded::ShardedHashMap; use rustc_data_structures::sync::{Lrc, Lock, WorkerLocal}; use std::any::Any; @@ -777,7 +777,7 @@ impl<'a, 'tcx> HashStable> for TypeckTables<'tcx> { } } -newtype_index! { +rustc_index::newtype_index! { pub struct UserTypeAnnotationIndex { derive [HashStable] DEBUG_FORMAT = "UserType({})", diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index eb2e1de7787..6b22ded49f3 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -18,8 +18,8 @@ use crate::mir::{GeneratorLayout, GeneratorSavedLocal}; use crate::ty::GeneratorSubsts; use crate::ty::subst::Subst; use rustc_index::bit_set::BitSet; -use rustc_data_structures::indexed_vec::{IndexVec, Idx}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +use rustc_index::vec::{IndexVec, Idx}; pub use rustc_target::abi::*; use rustc_target::spec::{HasTargetSpec, abi::Abi as SpecAbi}; diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 731aca854a4..269f87c441a 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -51,8 +51,8 @@ use syntax_pos::Span; use smallvec; use rustc_data_structures::fx::FxIndexMap; -use rustc_data_structures::indexed_vec::{Idx, IndexVec}; use rustc_data_structures::stable_hasher::{StableHasher, HashStable}; +use rustc_index::vec::{Idx, IndexVec}; use crate::hir; @@ -1536,7 +1536,7 @@ impl<'tcx> InstantiatedPredicates<'tcx> { } } -newtype_index! { +rustc_index::newtype_index! { /// "Universes" are used during type- and trait-checking in the /// presence of `for<..>` binders to control what sets of names are /// visible. Universes are arranged into a tree: the root universe diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs index e5c3a8402a7..863721a5b4b 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -43,7 +43,7 @@ use crate::util::profiling::ProfileCategory::*; use rustc_data_structures::svh::Svh; use rustc_index::bit_set::BitSet; -use rustc_data_structures::indexed_vec::IndexVec; +use rustc_index::vec::IndexVec; use rustc_data_structures::fx::{FxIndexMap, FxHashMap, FxHashSet}; use rustc_data_structures::stable_hasher::StableVec; use rustc_data_structures::sync::Lrc; diff --git a/src/librustc/ty/query/on_disk_cache.rs b/src/librustc/ty/query/on_disk_cache.rs index c20e7586889..97fafe341a3 100644 --- a/src/librustc/ty/query/on_disk_cache.rs +++ b/src/librustc/ty/query/on_disk_cache.rs @@ -15,7 +15,7 @@ use errors::Diagnostic; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::thin_vec::ThinVec; use rustc_data_structures::sync::{Lrc, Lock, HashMapExt, Once}; -use rustc_data_structures::indexed_vec::{IndexVec, Idx}; +use rustc_index::vec::{IndexVec, Idx}; use rustc_serialize::{ Decodable, Decoder, Encodable, Encoder, SpecializedDecoder, SpecializedEncoder, UseSpecializedDecodable, UseSpecializedEncodable, opaque, diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 42d632d120e..6b0df7fb92a 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -9,7 +9,7 @@ use crate::mir::interpret::ConstValue; use crate::ty::{self, Lift, Ty, TyCtxt, InferConst}; use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; use crate::ty::print::{FmtPrinter, Printer}; -use rustc_data_structures::indexed_vec::{IndexVec, Idx}; +use rustc_index::vec::{IndexVec, Idx}; use smallvec::SmallVec; use crate::mir::interpret; diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 91479751ef4..239c5796825 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -8,7 +8,7 @@ use crate::infer::canonical::Canonical; use crate::mir::interpret::ConstValue; use crate::middle::region; use polonius_engine::Atom; -use rustc_data_structures::indexed_vec::Idx; +use rustc_index::vec::Idx; use rustc_macros::HashStable; use crate::ty::subst::{InternalSubsts, Subst, SubstsRef, GenericArg, GenericArgKind}; use crate::ty::{self, AdtDef, Discr, DefIdTree, TypeFlags, Ty, TyCtxt, TypeFoldable}; @@ -1165,7 +1165,7 @@ impl<'tcx> ParamConst { } } -newtype_index! { +rustc_index::newtype_index! { /// A [De Bruijn index][dbi] is a standard means of representing /// regions (and perhaps later types) in a higher-ranked setting. In /// particular, imagine a type like this: @@ -1349,7 +1349,7 @@ pub struct FloatVid { pub index: u32, } -newtype_index! { +rustc_index::newtype_index! { pub struct RegionVid { DEBUG_FORMAT = custom, } @@ -1376,7 +1376,7 @@ pub enum InferTy { FreshFloatTy(u32), } -newtype_index! { +rustc_index::newtype_index! { pub struct BoundVar { .. } } diff --git a/src/librustc_codegen_llvm/Cargo.toml b/src/librustc_codegen_llvm/Cargo.toml index 540ab2a352a..98efa6a5804 100644 --- a/src/librustc_codegen_llvm/Cargo.toml +++ b/src/librustc_codegen_llvm/Cargo.toml @@ -12,7 +12,6 @@ test = false [dependencies] rustc_llvm = { path = "../librustc_llvm" } -rustc_index = { path = "../librustc_index" } [features] # This is used to convince Cargo to separately cache builds of `rustc_codegen_llvm` diff --git a/src/librustc_codegen_llvm/debuginfo/create_scope_map.rs b/src/librustc_codegen_llvm/debuginfo/create_scope_map.rs index 45af55a7be7..bdb7467a101 100644 --- a/src/librustc_codegen_llvm/debuginfo/create_scope_map.rs +++ b/src/librustc_codegen_llvm/debuginfo/create_scope_map.rs @@ -12,7 +12,7 @@ use libc::c_uint; use syntax_pos::Pos; use rustc_index::bit_set::BitSet; -use rustc_data_structures::indexed_vec::{Idx, IndexVec}; +use rustc_index::vec::{Idx, IndexVec}; use syntax_pos::BytePos; diff --git a/src/librustc_codegen_llvm/debuginfo/mod.rs b/src/librustc_codegen_llvm/debuginfo/mod.rs index 4efa1993d43..e0e0cd5f739 100644 --- a/src/librustc_codegen_llvm/debuginfo/mod.rs +++ b/src/librustc_codegen_llvm/debuginfo/mod.rs @@ -26,7 +26,7 @@ use rustc::mir; use rustc::session::config::{self, DebugInfo}; use rustc::util::nodemap::{DefIdMap, FxHashMap, FxHashSet}; use rustc_data_structures::small_c_str::SmallCStr; -use rustc_data_structures::indexed_vec::IndexVec; +use rustc_index::vec::IndexVec; use rustc_codegen_ssa::debuginfo::{FunctionDebugContext, MirDebugScope, VariableAccess, VariableKind, FunctionDebugContextData, type_names}; diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs index 2a63011c2f5..309a17a01e3 100644 --- a/src/librustc_codegen_llvm/lib.rs +++ b/src/librustc_codegen_llvm/lib.rs @@ -31,6 +31,7 @@ extern crate libc; #[macro_use] extern crate rustc; extern crate rustc_target; #[macro_use] extern crate rustc_data_structures; +extern crate rustc_index; extern crate rustc_incremental; extern crate rustc_codegen_utils; extern crate rustc_codegen_ssa; diff --git a/src/librustc_codegen_ssa/back/symbol_export.rs b/src/librustc_codegen_ssa/back/symbol_export.rs index d634b73430a..9078f77f1f7 100644 --- a/src/librustc_codegen_ssa/back/symbol_export.rs +++ b/src/librustc_codegen_ssa/back/symbol_export.rs @@ -13,7 +13,7 @@ use rustc::ty::{TyCtxt, SymbolName}; use rustc::ty::query::Providers; use rustc::ty::subst::SubstsRef; use rustc::util::nodemap::{FxHashMap, DefIdMap}; -use rustc_data_structures::indexed_vec::IndexVec; +use rustc_index::vec::IndexVec; use syntax::ext::allocator::ALLOCATOR_METHODS; pub type ExportedSymbols = FxHashMap< diff --git a/src/librustc_codegen_ssa/base.rs b/src/librustc_codegen_ssa/base.rs index 90ed629bbc6..d11d8911a93 100644 --- a/src/librustc_codegen_ssa/base.rs +++ b/src/librustc_codegen_ssa/base.rs @@ -29,7 +29,7 @@ use rustc::util::common::{time, print_time_passes_entry, set_time_depth, time_de use rustc::session::config::{self, EntryFnType, Lto}; use rustc::session::Session; use rustc::util::nodemap::FxHashMap; -use rustc_data_structures::indexed_vec::Idx; +use rustc_index::vec::Idx; use rustc_codegen_utils::{symbol_names_test, check_for_rustc_errors_attr}; use rustc::ty::layout::{FAT_PTR_ADDR, FAT_PTR_EXTRA}; use crate::mir::place::PlaceRef; diff --git a/src/librustc_codegen_ssa/mir/analyze.rs b/src/librustc_codegen_ssa/mir/analyze.rs index 9dc3d956aaf..ea1cf926fcc 100644 --- a/src/librustc_codegen_ssa/mir/analyze.rs +++ b/src/librustc_codegen_ssa/mir/analyze.rs @@ -3,7 +3,7 @@ use rustc_index::bit_set::BitSet; use rustc_data_structures::graph::dominators::Dominators; -use rustc_data_structures::indexed_vec::{Idx, IndexVec}; +use rustc_index::vec::{Idx, IndexVec}; use rustc::mir::{self, Location, TerminatorKind}; use rustc::mir::visit::{Visitor, PlaceContext, MutatingUseContext, NonMutatingUseContext}; use rustc::mir::traversal; diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs index 7ebdfbdcdeb..3a1d0a25775 100644 --- a/src/librustc_codegen_ssa/mir/block.rs +++ b/src/librustc_codegen_ssa/mir/block.rs @@ -1,4 +1,4 @@ -use rustc_data_structures::indexed_vec::Idx; +use rustc_index::vec::Idx; use rustc::middle::lang_items; use rustc::ty::{self, Ty, TypeFoldable, Instance}; use rustc::ty::layout::{self, LayoutOf, HasTyCtxt, FnTypeExt}; diff --git a/src/librustc_codegen_ssa/mir/constant.rs b/src/librustc_codegen_ssa/mir/constant.rs index 9cfe410fcc5..d06359ab0ce 100644 --- a/src/librustc_codegen_ssa/mir/constant.rs +++ b/src/librustc_codegen_ssa/mir/constant.rs @@ -1,6 +1,6 @@ use rustc::mir::interpret::ErrorHandled; use rustc::mir; -use rustc_data_structures::indexed_vec::Idx; +use rustc_index::vec::Idx; use rustc::ty::{self, Ty}; use rustc::ty::layout::{self, HasTyCtxt}; use syntax::source_map::Span; diff --git a/src/librustc_codegen_ssa/mir/mod.rs b/src/librustc_codegen_ssa/mir/mod.rs index 7cf8a69cee3..2a563e8290e 100644 --- a/src/librustc_codegen_ssa/mir/mod.rs +++ b/src/librustc_codegen_ssa/mir/mod.rs @@ -14,7 +14,7 @@ use syntax::symbol::kw; use std::iter; use rustc_index::bit_set::BitSet; -use rustc_data_structures::indexed_vec::IndexVec; +use rustc_index::vec::IndexVec; use self::analyze::CleanupKind; use self::place::PlaceRef; diff --git a/src/librustc_codegen_ssa/traits/debuginfo.rs b/src/librustc_codegen_ssa/traits/debuginfo.rs index 9c16b864ef2..e75f247da96 100644 --- a/src/librustc_codegen_ssa/traits/debuginfo.rs +++ b/src/librustc_codegen_ssa/traits/debuginfo.rs @@ -3,7 +3,7 @@ use crate::debuginfo::{FunctionDebugContext, MirDebugScope, VariableAccess, Vari use rustc::hir::def_id::CrateNum; use rustc::mir; use rustc::ty::{self, Ty, Instance}; -use rustc_data_structures::indexed_vec::IndexVec; +use rustc_index::vec::IndexVec; use syntax::ast::Name; use syntax_pos::{SourceFile, Span}; diff --git a/src/librustc_data_structures/graph/dominators/mod.rs b/src/librustc_data_structures/graph/dominators/mod.rs index 41e6b72953e..29a8a98d229 100644 --- a/src/librustc_data_structures/graph/dominators/mod.rs +++ b/src/librustc_data_structures/graph/dominators/mod.rs @@ -4,7 +4,7 @@ //! Rice Computer Science TS-06-33870 //! -use super::super::indexed_vec::{Idx, IndexVec}; +use rustc_index::vec::{Idx, IndexVec}; use super::iterate::reverse_post_order; use super::ControlFlowGraph; diff --git a/src/librustc_data_structures/graph/iterate/mod.rs b/src/librustc_data_structures/graph/iterate/mod.rs index 999c5df7b86..e268b281744 100644 --- a/src/librustc_data_structures/graph/iterate/mod.rs +++ b/src/librustc_data_structures/graph/iterate/mod.rs @@ -1,4 +1,4 @@ -use super::super::indexed_vec::IndexVec; +use rustc_index::vec::IndexVec; use super::{DirectedGraph, WithNumNodes, WithSuccessors, WithStartNode}; use rustc_index::bit_set::BitSet; diff --git a/src/librustc_data_structures/graph/mod.rs b/src/librustc_data_structures/graph/mod.rs index 0a607659f3e..37335799d19 100644 --- a/src/librustc_data_structures/graph/mod.rs +++ b/src/librustc_data_structures/graph/mod.rs @@ -1,4 +1,4 @@ -use super::indexed_vec::Idx; +use rustc_index::vec::Idx; pub mod dominators; pub mod implementation; diff --git a/src/librustc_data_structures/graph/scc/mod.rs b/src/librustc_data_structures/graph/scc/mod.rs index 23a1a2a90a4..c214f66cd15 100644 --- a/src/librustc_data_structures/graph/scc/mod.rs +++ b/src/librustc_data_structures/graph/scc/mod.rs @@ -6,7 +6,7 @@ use crate::fx::FxHashSet; use crate::graph::{DirectedGraph, WithNumNodes, WithNumEdges, WithSuccessors, GraphSuccessors}; use crate::graph::vec_graph::VecGraph; -use crate::indexed_vec::{Idx, IndexVec}; +use rustc_index::vec::{Idx, IndexVec}; use std::ops::Range; #[cfg(test)] diff --git a/src/librustc_data_structures/graph/vec_graph/mod.rs b/src/librustc_data_structures/graph/vec_graph/mod.rs index 19c61f2680d..aad5944dcd0 100644 --- a/src/librustc_data_structures/graph/vec_graph/mod.rs +++ b/src/librustc_data_structures/graph/vec_graph/mod.rs @@ -1,4 +1,4 @@ -use crate::indexed_vec::{Idx, IndexVec}; +use rustc_index::vec::{Idx, IndexVec}; use crate::graph::{DirectedGraph, WithNumNodes, WithNumEdges, WithSuccessors, GraphSuccessors}; #[cfg(test)] diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index 6a4602da36d..474a42644d9 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -37,7 +37,6 @@ extern crate libc; extern crate cfg_if; pub use rustc_serialize::hex::ToHex; -pub use rustc_index::{indexed_vec, newtype_index}; #[inline(never)] #[cold] diff --git a/src/librustc_data_structures/obligation_forest/mod.rs b/src/librustc_data_structures/obligation_forest/mod.rs index 1c7109fe500..cfccef67fe7 100644 --- a/src/librustc_data_structures/obligation_forest/mod.rs +++ b/src/librustc_data_structures/obligation_forest/mod.rs @@ -138,7 +138,7 @@ pub struct ObligationForest { /// call to `compress`. /// /// `usize` indices are used here and throughout this module, rather than - /// `newtype_index!` indices, because this code is hot enough that the + /// `rustc_index::newtype_index!` indices, because this code is hot enough that the /// `u32`-to-`usize` conversions that would be required are significant, /// and space considerations are not important. nodes: Vec>, diff --git a/src/librustc_data_structures/stable_hasher.rs b/src/librustc_data_structures/stable_hasher.rs index 7f17a1aed62..ee4f6a5e785 100644 --- a/src/librustc_data_structures/stable_hasher.rs +++ b/src/librustc_data_structures/stable_hasher.rs @@ -2,7 +2,7 @@ use std::hash::{Hash, Hasher, BuildHasher}; use std::mem; use smallvec::SmallVec; use crate::sip128::SipHasher128; -use crate::indexed_vec; +use rustc_index::vec; use rustc_index::bit_set; /// When hashing something that ends up affecting properties like symbol names, @@ -429,7 +429,7 @@ impl HashStable for ::std::mem::Discriminant { } } -impl HashStable for indexed_vec::IndexVec +impl HashStable for vec::IndexVec where T: HashStable, { fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { @@ -441,14 +441,14 @@ impl HashStable for indexed_vec::IndexVec HashStable for bit_set::BitSet +impl HashStable for bit_set::BitSet { fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { self.words().hash_stable(ctx, hasher); } } -impl HashStable +impl HashStable for bit_set::BitMatrix { fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { diff --git a/src/librustc_data_structures/vec_linked_list.rs b/src/librustc_data_structures/vec_linked_list.rs index 0fb80600318..7744c30655d 100644 --- a/src/librustc_data_structures/vec_linked_list.rs +++ b/src/librustc_data_structures/vec_linked_list.rs @@ -1,4 +1,4 @@ -use crate::indexed_vec::{Idx, IndexVec}; +use rustc_index::vec::{Idx, IndexVec}; pub fn iter( first: Option, diff --git a/src/librustc_data_structures/work_queue.rs b/src/librustc_data_structures/work_queue.rs index 2c0e2261fee..af63b18e9e9 100644 --- a/src/librustc_data_structures/work_queue.rs +++ b/src/librustc_data_structures/work_queue.rs @@ -1,5 +1,5 @@ use rustc_index::bit_set::BitSet; -use crate::indexed_vec::Idx; +use rustc_index::vec::Idx; use std::collections::VecDeque; /// A work queue is a handy data structure for tracking work left to diff --git a/src/librustc_index/bit_set.rs b/src/librustc_index/bit_set.rs index fe8ef642430..9c96645ccf9 100644 --- a/src/librustc_index/bit_set.rs +++ b/src/librustc_index/bit_set.rs @@ -1,4 +1,4 @@ -use crate::indexed_vec::{Idx, IndexVec}; +use crate::vec::{Idx, IndexVec}; use smallvec::SmallVec; use std::fmt; use std::iter; diff --git a/src/librustc_index/indexed_vec.rs b/src/librustc_index/indexed_vec.rs deleted file mode 100644 index 6e80b48a685..00000000000 --- a/src/librustc_index/indexed_vec.rs +++ /dev/null @@ -1,830 +0,0 @@ -use rustc_serialize::{Encodable, Decodable, Encoder, Decoder}; - -use std::fmt::Debug; -use std::iter::{self, FromIterator}; -use std::slice; -use std::marker::PhantomData; -use std::ops::{Index, IndexMut, Range, RangeBounds}; -use std::fmt; -use std::hash::Hash; -use std::vec; -use std::u32; - -/// Represents some newtyped `usize` wrapper. -/// -/// Purpose: avoid mixing indexes for different bitvector domains. -pub trait Idx: Copy + 'static + Ord + Debug + Hash { - fn new(idx: usize) -> Self; - - fn index(self) -> usize; - - fn increment_by(&mut self, amount: usize) { - *self = self.plus(amount); - } - - fn plus(self, amount: usize) -> Self { - Self::new(self.index() + amount) - } -} - -impl Idx for usize { - #[inline] - fn new(idx: usize) -> Self { idx } - #[inline] - fn index(self) -> usize { self } -} - -impl Idx for u32 { - #[inline] - fn new(idx: usize) -> Self { assert!(idx <= u32::MAX as usize); idx as u32 } - #[inline] - fn index(self) -> usize { self as usize } -} - -/// Creates a struct type `S` that can be used as an index with -/// `IndexVec` and so on. -/// -/// There are two ways of interacting with these indices: -/// -/// - The `From` impls are the preferred way. So you can do -/// `S::from(v)` with a `usize` or `u32`. And you can convert back -/// to an integer with `u32::from(s)`. -/// -/// - Alternatively, you can use the methods `S::new(v)` and `s.index()` -/// to create/return a value. -/// -/// Internally, the index uses a u32, so the index must not exceed -/// `u32::MAX`. You can also customize things like the `Debug` impl, -/// what traits are derived, and so forth via the macro. -#[macro_export] -#[allow_internal_unstable(step_trait, rustc_attrs)] -macro_rules! newtype_index { - // ---- public rules ---- - - // Use default constants - ($(#[$attrs:meta])* $v:vis struct $name:ident { .. }) => ( - $crate::newtype_index!( - // Leave out derives marker so we can use its absence to ensure it comes first - @attrs [$(#[$attrs])*] - @type [$name] - // shave off 256 indices at the end to allow space for packing these indices into enums - @max [0xFFFF_FF00] - @vis [$v] - @debug_format ["{}"]); - ); - - // Define any constants - ($(#[$attrs:meta])* $v:vis struct $name:ident { $($tokens:tt)+ }) => ( - $crate::newtype_index!( - // Leave out derives marker so we can use its absence to ensure it comes first - @attrs [$(#[$attrs])*] - @type [$name] - // shave off 256 indices at the end to allow space for packing these indices into enums - @max [0xFFFF_FF00] - @vis [$v] - @debug_format ["{}"] - $($tokens)+); - ); - - // ---- private rules ---- - - // Base case, user-defined constants (if any) have already been defined - (@derives [$($derives:ident,)*] - @attrs [$(#[$attrs:meta])*] - @type [$type:ident] - @max [$max:expr] - @vis [$v:vis] - @debug_format [$debug_format:tt]) => ( - $(#[$attrs])* - #[derive(Copy, PartialEq, Eq, Hash, PartialOrd, Ord, $($derives),*)] - #[rustc_layout_scalar_valid_range_end($max)] - $v struct $type { - private: u32 - } - - impl Clone for $type { - fn clone(&self) -> Self { - *self - } - } - - impl $type { - $v const MAX_AS_U32: u32 = $max; - - $v const MAX: $type = $type::from_u32_const($max); - - #[inline] - $v fn from_usize(value: usize) -> Self { - assert!(value <= ($max as usize)); - unsafe { - $type::from_u32_unchecked(value as u32) - } - } - - #[inline] - $v fn from_u32(value: u32) -> Self { - assert!(value <= $max); - unsafe { - $type::from_u32_unchecked(value) - } - } - - /// Hacky variant of `from_u32` for use in constants. - /// This version checks the "max" constraint by using an - /// invalid array dereference. - #[inline] - $v const fn from_u32_const(value: u32) -> Self { - // This will fail at const eval time unless `value <= - // max` is true (in which case we get the index 0). - // It will also fail at runtime, of course, but in a - // kind of wacky way. - let _ = ["out of range value used"][ - !(value <= $max) as usize - ]; - - unsafe { - $type { private: value } - } - } - - #[inline] - $v const unsafe fn from_u32_unchecked(value: u32) -> Self { - $type { private: value } - } - - /// Extracts the value of this index as an integer. - #[inline] - $v fn index(self) -> usize { - self.as_usize() - } - - /// Extracts the value of this index as a `u32`. - #[inline] - $v fn as_u32(self) -> u32 { - self.private - } - - /// Extracts the value of this index as a `usize`. - #[inline] - $v fn as_usize(self) -> usize { - self.as_u32() as usize - } - } - - impl std::ops::Add for $type { - type Output = Self; - - fn add(self, other: usize) -> Self { - Self::new(self.index() + other) - } - } - - impl Idx for $type { - #[inline] - fn new(value: usize) -> Self { - Self::from(value) - } - - #[inline] - fn index(self) -> usize { - usize::from(self) - } - } - - impl ::std::iter::Step for $type { - #[inline] - fn steps_between(start: &Self, end: &Self) -> Option { - ::steps_between( - &Idx::index(*start), - &Idx::index(*end), - ) - } - - #[inline] - fn replace_one(&mut self) -> Self { - ::std::mem::replace(self, Self::new(1)) - } - - #[inline] - fn replace_zero(&mut self) -> Self { - ::std::mem::replace(self, Self::new(0)) - } - - #[inline] - fn add_one(&self) -> Self { - Self::new(Idx::index(*self) + 1) - } - - #[inline] - fn sub_one(&self) -> Self { - Self::new(Idx::index(*self) - 1) - } - - #[inline] - fn add_usize(&self, u: usize) -> Option { - Idx::index(*self).checked_add(u).map(Self::new) - } - - #[inline] - fn sub_usize(&self, u: usize) -> Option { - Idx::index(*self).checked_sub(u).map(Self::new) - } - } - - impl From<$type> for u32 { - #[inline] - fn from(v: $type) -> u32 { - v.as_u32() - } - } - - impl From<$type> for usize { - #[inline] - fn from(v: $type) -> usize { - v.as_usize() - } - } - - impl From for $type { - #[inline] - fn from(value: usize) -> Self { - $type::from_usize(value) - } - } - - impl From for $type { - #[inline] - fn from(value: u32) -> Self { - $type::from_u32(value) - } - } - - $crate::newtype_index!( - @handle_debug - @derives [$($derives,)*] - @type [$type] - @debug_format [$debug_format]); - ); - - // base case for handle_debug where format is custom. No Debug implementation is emitted. - (@handle_debug - @derives [$($_derives:ident,)*] - @type [$type:ident] - @debug_format [custom]) => (); - - // base case for handle_debug, no debug overrides found, so use default - (@handle_debug - @derives [] - @type [$type:ident] - @debug_format [$debug_format:tt]) => ( - impl ::std::fmt::Debug for $type { - fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { - write!(fmt, $debug_format, self.as_u32()) - } - } - ); - - // Debug is requested for derive, don't generate any Debug implementation. - (@handle_debug - @derives [Debug, $($derives:ident,)*] - @type [$type:ident] - @debug_format [$debug_format:tt]) => (); - - // It's not Debug, so just pop it off the front of the derives stack and check the rest. - (@handle_debug - @derives [$_derive:ident, $($derives:ident,)*] - @type [$type:ident] - @debug_format [$debug_format:tt]) => ( - $crate::newtype_index!( - @handle_debug - @derives [$($derives,)*] - @type [$type] - @debug_format [$debug_format]); - ); - - // Append comma to end of derives list if it's missing - (@attrs [$(#[$attrs:meta])*] - @type [$type:ident] - @max [$max:expr] - @vis [$v:vis] - @debug_format [$debug_format:tt] - derive [$($derives:ident),*] - $($tokens:tt)*) => ( - $crate::newtype_index!( - @attrs [$(#[$attrs])*] - @type [$type] - @max [$max] - @vis [$v] - @debug_format [$debug_format] - derive [$($derives,)*] - $($tokens)*); - ); - - // By not including the @derives marker in this list nor in the default args, we can force it - // to come first if it exists. When encodable is custom, just use the derives list as-is. - (@attrs [$(#[$attrs:meta])*] - @type [$type:ident] - @max [$max:expr] - @vis [$v:vis] - @debug_format [$debug_format:tt] - derive [$($derives:ident,)+] - ENCODABLE = custom - $($tokens:tt)*) => ( - $crate::newtype_index!( - @attrs [$(#[$attrs])*] - @derives [$($derives,)+] - @type [$type] - @max [$max] - @vis [$v] - @debug_format [$debug_format] - $($tokens)*); - ); - - // By not including the @derives marker in this list nor in the default args, we can force it - // to come first if it exists. When encodable isn't custom, add serialization traits by default. - (@attrs [$(#[$attrs:meta])*] - @type [$type:ident] - @max [$max:expr] - @vis [$v:vis] - @debug_format [$debug_format:tt] - derive [$($derives:ident,)+] - $($tokens:tt)*) => ( - $crate::newtype_index!( - @derives [$($derives,)+ RustcEncodable,] - @attrs [$(#[$attrs])*] - @type [$type] - @max [$max] - @vis [$v] - @debug_format [$debug_format] - $($tokens)*); - $crate::newtype_index!(@decodable $type); - ); - - // The case where no derives are added, but encodable is overridden. Don't - // derive serialization traits - (@attrs [$(#[$attrs:meta])*] - @type [$type:ident] - @max [$max:expr] - @vis [$v:vis] - @debug_format [$debug_format:tt] - ENCODABLE = custom - $($tokens:tt)*) => ( - $crate::newtype_index!( - @derives [] - @attrs [$(#[$attrs])*] - @type [$type] - @max [$max] - @vis [$v] - @debug_format [$debug_format] - $($tokens)*); - ); - - // The case where no derives are added, add serialization derives by default - (@attrs [$(#[$attrs:meta])*] - @type [$type:ident] - @max [$max:expr] - @vis [$v:vis] - @debug_format [$debug_format:tt] - $($tokens:tt)*) => ( - $crate::newtype_index!( - @derives [RustcEncodable,] - @attrs [$(#[$attrs])*] - @type [$type] - @max [$max] - @vis [$v] - @debug_format [$debug_format] - $($tokens)*); - $crate::newtype_index!(@decodable $type); - ); - - (@decodable $type:ident) => ( - impl ::rustc_serialize::Decodable for $type { - fn decode(d: &mut D) -> Result { - d.read_u32().map(Self::from) - } - } - ); - - // Rewrite final without comma to one that includes comma - (@derives [$($derives:ident,)*] - @attrs [$(#[$attrs:meta])*] - @type [$type:ident] - @max [$max:expr] - @vis [$v:vis] - @debug_format [$debug_format:tt] - $name:ident = $constant:expr) => ( - $crate::newtype_index!( - @derives [$($derives,)*] - @attrs [$(#[$attrs])*] - @type [$type] - @max [$max] - @vis [$v] - @debug_format [$debug_format] - $name = $constant,); - ); - - // Rewrite final const without comma to one that includes comma - (@derives [$($derives:ident,)*] - @attrs [$(#[$attrs:meta])*] - @type [$type:ident] - @max [$max:expr] - @vis [$v:vis] - @debug_format [$debug_format:tt] - $(#[doc = $doc:expr])* - const $name:ident = $constant:expr) => ( - $crate::newtype_index!( - @derives [$($derives,)*] - @attrs [$(#[$attrs])*] - @type [$type] - @max [$max] - @vis [$v] - @debug_format [$debug_format] - $(#[doc = $doc])* const $name = $constant,); - ); - - // Replace existing default for max - (@derives [$($derives:ident,)*] - @attrs [$(#[$attrs:meta])*] - @type [$type:ident] - @max [$_max:expr] - @vis [$v:vis] - @debug_format [$debug_format:tt] - MAX = $max:expr, - $($tokens:tt)*) => ( - $crate::newtype_index!( - @derives [$($derives,)*] - @attrs [$(#[$attrs])*] - @type [$type] - @max [$max] - @vis [$v] - @debug_format [$debug_format] - $($tokens)*); - ); - - // Replace existing default for debug_format - (@derives [$($derives:ident,)*] - @attrs [$(#[$attrs:meta])*] - @type [$type:ident] - @max [$max:expr] - @vis [$v:vis] - @debug_format [$_debug_format:tt] - DEBUG_FORMAT = $debug_format:tt, - $($tokens:tt)*) => ( - $crate::newtype_index!( - @derives [$($derives,)*] - @attrs [$(#[$attrs])*] - @type [$type] - @max [$max] - @vis [$v] - @debug_format [$debug_format] - $($tokens)*); - ); - - // Assign a user-defined constant - (@derives [$($derives:ident,)*] - @attrs [$(#[$attrs:meta])*] - @type [$type:ident] - @max [$max:expr] - @vis [$v:vis] - @debug_format [$debug_format:tt] - $(#[doc = $doc:expr])* - const $name:ident = $constant:expr, - $($tokens:tt)*) => ( - $(#[doc = $doc])* - pub const $name: $type = $type::from_u32_const($constant); - $crate::newtype_index!( - @derives [$($derives,)*] - @attrs [$(#[$attrs])*] - @type [$type] - @max [$max] - @vis [$v] - @debug_format [$debug_format] - $($tokens)*); - ); -} - -#[derive(Clone, PartialEq, Eq, Hash)] -pub struct IndexVec { - pub raw: Vec, - _marker: PhantomData -} - -// Whether `IndexVec` is `Send` depends only on the data, -// not the phantom data. -unsafe impl Send for IndexVec where T: Send {} - -impl Encodable for IndexVec { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - Encodable::encode(&self.raw, s) - } -} - -impl Decodable for IndexVec { - fn decode(d: &mut D) -> Result { - Decodable::decode(d).map(|v| { - IndexVec { raw: v, _marker: PhantomData } - }) - } -} - -impl fmt::Debug for IndexVec { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Debug::fmt(&self.raw, fmt) - } -} - -pub type Enumerated = iter::Map, IntoIdx>; - -impl IndexVec { - #[inline] - pub fn new() -> Self { - IndexVec { raw: Vec::new(), _marker: PhantomData } - } - - #[inline] - pub fn from_raw(raw: Vec) -> Self { - IndexVec { raw, _marker: PhantomData } - } - - #[inline] - pub fn with_capacity(capacity: usize) -> Self { - IndexVec { raw: Vec::with_capacity(capacity), _marker: PhantomData } - } - - #[inline] - pub fn from_elem(elem: T, universe: &IndexVec) -> Self - where T: Clone - { - IndexVec { raw: vec![elem; universe.len()], _marker: PhantomData } - } - - #[inline] - pub fn from_elem_n(elem: T, n: usize) -> Self - where T: Clone - { - IndexVec { raw: vec![elem; n], _marker: PhantomData } - } - - #[inline] - pub fn push(&mut self, d: T) -> I { - let idx = I::new(self.len()); - self.raw.push(d); - idx - } - - #[inline] - pub fn pop(&mut self) -> Option { - self.raw.pop() - } - - #[inline] - pub fn len(&self) -> usize { - self.raw.len() - } - - /// Gives the next index that will be assigned when `push` is - /// called. - #[inline] - pub fn next_index(&self) -> I { - I::new(self.len()) - } - - #[inline] - pub fn is_empty(&self) -> bool { - self.raw.is_empty() - } - - #[inline] - pub fn into_iter(self) -> vec::IntoIter { - self.raw.into_iter() - } - - #[inline] - pub fn into_iter_enumerated(self) -> Enumerated> - { - self.raw.into_iter().enumerate().map(IntoIdx { _marker: PhantomData }) - } - - #[inline] - pub fn iter(&self) -> slice::Iter<'_, T> { - self.raw.iter() - } - - #[inline] - pub fn iter_enumerated(&self) -> Enumerated> - { - self.raw.iter().enumerate().map(IntoIdx { _marker: PhantomData }) - } - - #[inline] - pub fn indices(&self) -> iter::Map, IntoIdx> { - (0..self.len()).map(IntoIdx { _marker: PhantomData }) - } - - #[inline] - pub fn iter_mut(&mut self) -> slice::IterMut<'_, T> { - self.raw.iter_mut() - } - - #[inline] - pub fn iter_enumerated_mut(&mut self) -> Enumerated> - { - self.raw.iter_mut().enumerate().map(IntoIdx { _marker: PhantomData }) - } - - #[inline] - pub fn drain<'a, R: RangeBounds>( - &'a mut self, range: R) -> impl Iterator + 'a { - self.raw.drain(range) - } - - #[inline] - pub fn drain_enumerated<'a, R: RangeBounds>( - &'a mut self, range: R) -> impl Iterator + 'a { - self.raw.drain(range).enumerate().map(IntoIdx { _marker: PhantomData }) - } - - #[inline] - pub fn last(&self) -> Option { - self.len().checked_sub(1).map(I::new) - } - - #[inline] - pub fn shrink_to_fit(&mut self) { - self.raw.shrink_to_fit() - } - - #[inline] - pub fn swap(&mut self, a: I, b: I) { - self.raw.swap(a.index(), b.index()) - } - - #[inline] - pub fn truncate(&mut self, a: usize) { - self.raw.truncate(a) - } - - #[inline] - pub fn get(&self, index: I) -> Option<&T> { - self.raw.get(index.index()) - } - - #[inline] - pub fn get_mut(&mut self, index: I) -> Option<&mut T> { - self.raw.get_mut(index.index()) - } - - /// Returns mutable references to two distinct elements, a and b. Panics if a == b. - #[inline] - pub fn pick2_mut(&mut self, a: I, b: I) -> (&mut T, &mut T) { - let (ai, bi) = (a.index(), b.index()); - assert!(ai != bi); - - if ai < bi { - let (c1, c2) = self.raw.split_at_mut(bi); - (&mut c1[ai], &mut c2[0]) - } else { - let (c2, c1) = self.pick2_mut(b, a); - (c1, c2) - } - } - - pub fn convert_index_type(self) -> IndexVec { - IndexVec { - raw: self.raw, - _marker: PhantomData, - } - } -} - -impl IndexVec { - /// Grows the index vector so that it contains an entry for - /// `elem`; if that is already true, then has no - /// effect. Otherwise, inserts new values as needed by invoking - /// `fill_value`. - #[inline] - pub fn ensure_contains_elem(&mut self, elem: I, fill_value: impl FnMut() -> T) { - let min_new_len = elem.index() + 1; - if self.len() < min_new_len { - self.raw.resize_with(min_new_len, fill_value); - } - } - - #[inline] - pub fn resize(&mut self, new_len: usize, value: T) { - self.raw.resize(new_len, value) - } - - #[inline] - pub fn resize_to_elem(&mut self, elem: I, fill_value: impl FnMut() -> T) { - let min_new_len = elem.index() + 1; - self.raw.resize_with(min_new_len, fill_value); - } -} - -impl IndexVec { - #[inline] - pub fn binary_search(&self, value: &T) -> Result { - match self.raw.binary_search(value) { - Ok(i) => Ok(Idx::new(i)), - Err(i) => Err(Idx::new(i)), - } - } -} - -impl Index for IndexVec { - type Output = T; - - #[inline] - fn index(&self, index: I) -> &T { - &self.raw[index.index()] - } -} - -impl IndexMut for IndexVec { - #[inline] - fn index_mut(&mut self, index: I) -> &mut T { - &mut self.raw[index.index()] - } -} - -impl Default for IndexVec { - #[inline] - fn default() -> Self { - Self::new() - } -} - -impl Extend for IndexVec { - #[inline] - fn extend>(&mut self, iter: J) { - self.raw.extend(iter); - } -} - -impl FromIterator for IndexVec { - #[inline] - fn from_iter(iter: J) -> Self where J: IntoIterator { - IndexVec { raw: FromIterator::from_iter(iter), _marker: PhantomData } - } -} - -impl IntoIterator for IndexVec { - type Item = T; - type IntoIter = vec::IntoIter; - - #[inline] - fn into_iter(self) -> vec::IntoIter { - self.raw.into_iter() - } - -} - -impl<'a, I: Idx, T> IntoIterator for &'a IndexVec { - type Item = &'a T; - type IntoIter = slice::Iter<'a, T>; - - #[inline] - fn into_iter(self) -> slice::Iter<'a, T> { - self.raw.iter() - } -} - -impl<'a, I: Idx, T> IntoIterator for &'a mut IndexVec { - type Item = &'a mut T; - type IntoIter = slice::IterMut<'a, T>; - - #[inline] - fn into_iter(self) -> slice::IterMut<'a, T> { - self.raw.iter_mut() - } -} - -pub struct IntoIdx { _marker: PhantomData } -impl FnOnce<((usize, T),)> for IntoIdx { - type Output = (I, T); - - extern "rust-call" fn call_once(self, ((n, t),): ((usize, T),)) -> Self::Output { - (I::new(n), t) - } -} - -impl FnMut<((usize, T),)> for IntoIdx { - extern "rust-call" fn call_mut(&mut self, ((n, t),): ((usize, T),)) -> Self::Output { - (I::new(n), t) - } -} - -impl FnOnce<(usize,)> for IntoIdx { - type Output = I; - - extern "rust-call" fn call_once(self, (n,): (usize,)) -> Self::Output { - I::new(n) - } -} - -impl FnMut<(usize,)> for IntoIdx { - extern "rust-call" fn call_mut(&mut self, (n,): (usize,)) -> Self::Output { - I::new(n) - } -} diff --git a/src/librustc_index/lib.rs b/src/librustc_index/lib.rs index 5d7e0d82e78..ad242dfd2e0 100644 --- a/src/librustc_index/lib.rs +++ b/src/librustc_index/lib.rs @@ -3,5 +3,5 @@ #![feature(test)] #![feature(fn_traits)] -pub mod indexed_vec; +pub mod vec; pub mod bit_set; diff --git a/src/librustc_index/vec.rs b/src/librustc_index/vec.rs new file mode 100644 index 00000000000..6e80b48a685 --- /dev/null +++ b/src/librustc_index/vec.rs @@ -0,0 +1,830 @@ +use rustc_serialize::{Encodable, Decodable, Encoder, Decoder}; + +use std::fmt::Debug; +use std::iter::{self, FromIterator}; +use std::slice; +use std::marker::PhantomData; +use std::ops::{Index, IndexMut, Range, RangeBounds}; +use std::fmt; +use std::hash::Hash; +use std::vec; +use std::u32; + +/// Represents some newtyped `usize` wrapper. +/// +/// Purpose: avoid mixing indexes for different bitvector domains. +pub trait Idx: Copy + 'static + Ord + Debug + Hash { + fn new(idx: usize) -> Self; + + fn index(self) -> usize; + + fn increment_by(&mut self, amount: usize) { + *self = self.plus(amount); + } + + fn plus(self, amount: usize) -> Self { + Self::new(self.index() + amount) + } +} + +impl Idx for usize { + #[inline] + fn new(idx: usize) -> Self { idx } + #[inline] + fn index(self) -> usize { self } +} + +impl Idx for u32 { + #[inline] + fn new(idx: usize) -> Self { assert!(idx <= u32::MAX as usize); idx as u32 } + #[inline] + fn index(self) -> usize { self as usize } +} + +/// Creates a struct type `S` that can be used as an index with +/// `IndexVec` and so on. +/// +/// There are two ways of interacting with these indices: +/// +/// - The `From` impls are the preferred way. So you can do +/// `S::from(v)` with a `usize` or `u32`. And you can convert back +/// to an integer with `u32::from(s)`. +/// +/// - Alternatively, you can use the methods `S::new(v)` and `s.index()` +/// to create/return a value. +/// +/// Internally, the index uses a u32, so the index must not exceed +/// `u32::MAX`. You can also customize things like the `Debug` impl, +/// what traits are derived, and so forth via the macro. +#[macro_export] +#[allow_internal_unstable(step_trait, rustc_attrs)] +macro_rules! newtype_index { + // ---- public rules ---- + + // Use default constants + ($(#[$attrs:meta])* $v:vis struct $name:ident { .. }) => ( + $crate::newtype_index!( + // Leave out derives marker so we can use its absence to ensure it comes first + @attrs [$(#[$attrs])*] + @type [$name] + // shave off 256 indices at the end to allow space for packing these indices into enums + @max [0xFFFF_FF00] + @vis [$v] + @debug_format ["{}"]); + ); + + // Define any constants + ($(#[$attrs:meta])* $v:vis struct $name:ident { $($tokens:tt)+ }) => ( + $crate::newtype_index!( + // Leave out derives marker so we can use its absence to ensure it comes first + @attrs [$(#[$attrs])*] + @type [$name] + // shave off 256 indices at the end to allow space for packing these indices into enums + @max [0xFFFF_FF00] + @vis [$v] + @debug_format ["{}"] + $($tokens)+); + ); + + // ---- private rules ---- + + // Base case, user-defined constants (if any) have already been defined + (@derives [$($derives:ident,)*] + @attrs [$(#[$attrs:meta])*] + @type [$type:ident] + @max [$max:expr] + @vis [$v:vis] + @debug_format [$debug_format:tt]) => ( + $(#[$attrs])* + #[derive(Copy, PartialEq, Eq, Hash, PartialOrd, Ord, $($derives),*)] + #[rustc_layout_scalar_valid_range_end($max)] + $v struct $type { + private: u32 + } + + impl Clone for $type { + fn clone(&self) -> Self { + *self + } + } + + impl $type { + $v const MAX_AS_U32: u32 = $max; + + $v const MAX: $type = $type::from_u32_const($max); + + #[inline] + $v fn from_usize(value: usize) -> Self { + assert!(value <= ($max as usize)); + unsafe { + $type::from_u32_unchecked(value as u32) + } + } + + #[inline] + $v fn from_u32(value: u32) -> Self { + assert!(value <= $max); + unsafe { + $type::from_u32_unchecked(value) + } + } + + /// Hacky variant of `from_u32` for use in constants. + /// This version checks the "max" constraint by using an + /// invalid array dereference. + #[inline] + $v const fn from_u32_const(value: u32) -> Self { + // This will fail at const eval time unless `value <= + // max` is true (in which case we get the index 0). + // It will also fail at runtime, of course, but in a + // kind of wacky way. + let _ = ["out of range value used"][ + !(value <= $max) as usize + ]; + + unsafe { + $type { private: value } + } + } + + #[inline] + $v const unsafe fn from_u32_unchecked(value: u32) -> Self { + $type { private: value } + } + + /// Extracts the value of this index as an integer. + #[inline] + $v fn index(self) -> usize { + self.as_usize() + } + + /// Extracts the value of this index as a `u32`. + #[inline] + $v fn as_u32(self) -> u32 { + self.private + } + + /// Extracts the value of this index as a `usize`. + #[inline] + $v fn as_usize(self) -> usize { + self.as_u32() as usize + } + } + + impl std::ops::Add for $type { + type Output = Self; + + fn add(self, other: usize) -> Self { + Self::new(self.index() + other) + } + } + + impl Idx for $type { + #[inline] + fn new(value: usize) -> Self { + Self::from(value) + } + + #[inline] + fn index(self) -> usize { + usize::from(self) + } + } + + impl ::std::iter::Step for $type { + #[inline] + fn steps_between(start: &Self, end: &Self) -> Option { + ::steps_between( + &Idx::index(*start), + &Idx::index(*end), + ) + } + + #[inline] + fn replace_one(&mut self) -> Self { + ::std::mem::replace(self, Self::new(1)) + } + + #[inline] + fn replace_zero(&mut self) -> Self { + ::std::mem::replace(self, Self::new(0)) + } + + #[inline] + fn add_one(&self) -> Self { + Self::new(Idx::index(*self) + 1) + } + + #[inline] + fn sub_one(&self) -> Self { + Self::new(Idx::index(*self) - 1) + } + + #[inline] + fn add_usize(&self, u: usize) -> Option { + Idx::index(*self).checked_add(u).map(Self::new) + } + + #[inline] + fn sub_usize(&self, u: usize) -> Option { + Idx::index(*self).checked_sub(u).map(Self::new) + } + } + + impl From<$type> for u32 { + #[inline] + fn from(v: $type) -> u32 { + v.as_u32() + } + } + + impl From<$type> for usize { + #[inline] + fn from(v: $type) -> usize { + v.as_usize() + } + } + + impl From for $type { + #[inline] + fn from(value: usize) -> Self { + $type::from_usize(value) + } + } + + impl From for $type { + #[inline] + fn from(value: u32) -> Self { + $type::from_u32(value) + } + } + + $crate::newtype_index!( + @handle_debug + @derives [$($derives,)*] + @type [$type] + @debug_format [$debug_format]); + ); + + // base case for handle_debug where format is custom. No Debug implementation is emitted. + (@handle_debug + @derives [$($_derives:ident,)*] + @type [$type:ident] + @debug_format [custom]) => (); + + // base case for handle_debug, no debug overrides found, so use default + (@handle_debug + @derives [] + @type [$type:ident] + @debug_format [$debug_format:tt]) => ( + impl ::std::fmt::Debug for $type { + fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + write!(fmt, $debug_format, self.as_u32()) + } + } + ); + + // Debug is requested for derive, don't generate any Debug implementation. + (@handle_debug + @derives [Debug, $($derives:ident,)*] + @type [$type:ident] + @debug_format [$debug_format:tt]) => (); + + // It's not Debug, so just pop it off the front of the derives stack and check the rest. + (@handle_debug + @derives [$_derive:ident, $($derives:ident,)*] + @type [$type:ident] + @debug_format [$debug_format:tt]) => ( + $crate::newtype_index!( + @handle_debug + @derives [$($derives,)*] + @type [$type] + @debug_format [$debug_format]); + ); + + // Append comma to end of derives list if it's missing + (@attrs [$(#[$attrs:meta])*] + @type [$type:ident] + @max [$max:expr] + @vis [$v:vis] + @debug_format [$debug_format:tt] + derive [$($derives:ident),*] + $($tokens:tt)*) => ( + $crate::newtype_index!( + @attrs [$(#[$attrs])*] + @type [$type] + @max [$max] + @vis [$v] + @debug_format [$debug_format] + derive [$($derives,)*] + $($tokens)*); + ); + + // By not including the @derives marker in this list nor in the default args, we can force it + // to come first if it exists. When encodable is custom, just use the derives list as-is. + (@attrs [$(#[$attrs:meta])*] + @type [$type:ident] + @max [$max:expr] + @vis [$v:vis] + @debug_format [$debug_format:tt] + derive [$($derives:ident,)+] + ENCODABLE = custom + $($tokens:tt)*) => ( + $crate::newtype_index!( + @attrs [$(#[$attrs])*] + @derives [$($derives,)+] + @type [$type] + @max [$max] + @vis [$v] + @debug_format [$debug_format] + $($tokens)*); + ); + + // By not including the @derives marker in this list nor in the default args, we can force it + // to come first if it exists. When encodable isn't custom, add serialization traits by default. + (@attrs [$(#[$attrs:meta])*] + @type [$type:ident] + @max [$max:expr] + @vis [$v:vis] + @debug_format [$debug_format:tt] + derive [$($derives:ident,)+] + $($tokens:tt)*) => ( + $crate::newtype_index!( + @derives [$($derives,)+ RustcEncodable,] + @attrs [$(#[$attrs])*] + @type [$type] + @max [$max] + @vis [$v] + @debug_format [$debug_format] + $($tokens)*); + $crate::newtype_index!(@decodable $type); + ); + + // The case where no derives are added, but encodable is overridden. Don't + // derive serialization traits + (@attrs [$(#[$attrs:meta])*] + @type [$type:ident] + @max [$max:expr] + @vis [$v:vis] + @debug_format [$debug_format:tt] + ENCODABLE = custom + $($tokens:tt)*) => ( + $crate::newtype_index!( + @derives [] + @attrs [$(#[$attrs])*] + @type [$type] + @max [$max] + @vis [$v] + @debug_format [$debug_format] + $($tokens)*); + ); + + // The case where no derives are added, add serialization derives by default + (@attrs [$(#[$attrs:meta])*] + @type [$type:ident] + @max [$max:expr] + @vis [$v:vis] + @debug_format [$debug_format:tt] + $($tokens:tt)*) => ( + $crate::newtype_index!( + @derives [RustcEncodable,] + @attrs [$(#[$attrs])*] + @type [$type] + @max [$max] + @vis [$v] + @debug_format [$debug_format] + $($tokens)*); + $crate::newtype_index!(@decodable $type); + ); + + (@decodable $type:ident) => ( + impl ::rustc_serialize::Decodable for $type { + fn decode(d: &mut D) -> Result { + d.read_u32().map(Self::from) + } + } + ); + + // Rewrite final without comma to one that includes comma + (@derives [$($derives:ident,)*] + @attrs [$(#[$attrs:meta])*] + @type [$type:ident] + @max [$max:expr] + @vis [$v:vis] + @debug_format [$debug_format:tt] + $name:ident = $constant:expr) => ( + $crate::newtype_index!( + @derives [$($derives,)*] + @attrs [$(#[$attrs])*] + @type [$type] + @max [$max] + @vis [$v] + @debug_format [$debug_format] + $name = $constant,); + ); + + // Rewrite final const without comma to one that includes comma + (@derives [$($derives:ident,)*] + @attrs [$(#[$attrs:meta])*] + @type [$type:ident] + @max [$max:expr] + @vis [$v:vis] + @debug_format [$debug_format:tt] + $(#[doc = $doc:expr])* + const $name:ident = $constant:expr) => ( + $crate::newtype_index!( + @derives [$($derives,)*] + @attrs [$(#[$attrs])*] + @type [$type] + @max [$max] + @vis [$v] + @debug_format [$debug_format] + $(#[doc = $doc])* const $name = $constant,); + ); + + // Replace existing default for max + (@derives [$($derives:ident,)*] + @attrs [$(#[$attrs:meta])*] + @type [$type:ident] + @max [$_max:expr] + @vis [$v:vis] + @debug_format [$debug_format:tt] + MAX = $max:expr, + $($tokens:tt)*) => ( + $crate::newtype_index!( + @derives [$($derives,)*] + @attrs [$(#[$attrs])*] + @type [$type] + @max [$max] + @vis [$v] + @debug_format [$debug_format] + $($tokens)*); + ); + + // Replace existing default for debug_format + (@derives [$($derives:ident,)*] + @attrs [$(#[$attrs:meta])*] + @type [$type:ident] + @max [$max:expr] + @vis [$v:vis] + @debug_format [$_debug_format:tt] + DEBUG_FORMAT = $debug_format:tt, + $($tokens:tt)*) => ( + $crate::newtype_index!( + @derives [$($derives,)*] + @attrs [$(#[$attrs])*] + @type [$type] + @max [$max] + @vis [$v] + @debug_format [$debug_format] + $($tokens)*); + ); + + // Assign a user-defined constant + (@derives [$($derives:ident,)*] + @attrs [$(#[$attrs:meta])*] + @type [$type:ident] + @max [$max:expr] + @vis [$v:vis] + @debug_format [$debug_format:tt] + $(#[doc = $doc:expr])* + const $name:ident = $constant:expr, + $($tokens:tt)*) => ( + $(#[doc = $doc])* + pub const $name: $type = $type::from_u32_const($constant); + $crate::newtype_index!( + @derives [$($derives,)*] + @attrs [$(#[$attrs])*] + @type [$type] + @max [$max] + @vis [$v] + @debug_format [$debug_format] + $($tokens)*); + ); +} + +#[derive(Clone, PartialEq, Eq, Hash)] +pub struct IndexVec { + pub raw: Vec, + _marker: PhantomData +} + +// Whether `IndexVec` is `Send` depends only on the data, +// not the phantom data. +unsafe impl Send for IndexVec where T: Send {} + +impl Encodable for IndexVec { + fn encode(&self, s: &mut S) -> Result<(), S::Error> { + Encodable::encode(&self.raw, s) + } +} + +impl Decodable for IndexVec { + fn decode(d: &mut D) -> Result { + Decodable::decode(d).map(|v| { + IndexVec { raw: v, _marker: PhantomData } + }) + } +} + +impl fmt::Debug for IndexVec { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Debug::fmt(&self.raw, fmt) + } +} + +pub type Enumerated = iter::Map, IntoIdx>; + +impl IndexVec { + #[inline] + pub fn new() -> Self { + IndexVec { raw: Vec::new(), _marker: PhantomData } + } + + #[inline] + pub fn from_raw(raw: Vec) -> Self { + IndexVec { raw, _marker: PhantomData } + } + + #[inline] + pub fn with_capacity(capacity: usize) -> Self { + IndexVec { raw: Vec::with_capacity(capacity), _marker: PhantomData } + } + + #[inline] + pub fn from_elem(elem: T, universe: &IndexVec) -> Self + where T: Clone + { + IndexVec { raw: vec![elem; universe.len()], _marker: PhantomData } + } + + #[inline] + pub fn from_elem_n(elem: T, n: usize) -> Self + where T: Clone + { + IndexVec { raw: vec![elem; n], _marker: PhantomData } + } + + #[inline] + pub fn push(&mut self, d: T) -> I { + let idx = I::new(self.len()); + self.raw.push(d); + idx + } + + #[inline] + pub fn pop(&mut self) -> Option { + self.raw.pop() + } + + #[inline] + pub fn len(&self) -> usize { + self.raw.len() + } + + /// Gives the next index that will be assigned when `push` is + /// called. + #[inline] + pub fn next_index(&self) -> I { + I::new(self.len()) + } + + #[inline] + pub fn is_empty(&self) -> bool { + self.raw.is_empty() + } + + #[inline] + pub fn into_iter(self) -> vec::IntoIter { + self.raw.into_iter() + } + + #[inline] + pub fn into_iter_enumerated(self) -> Enumerated> + { + self.raw.into_iter().enumerate().map(IntoIdx { _marker: PhantomData }) + } + + #[inline] + pub fn iter(&self) -> slice::Iter<'_, T> { + self.raw.iter() + } + + #[inline] + pub fn iter_enumerated(&self) -> Enumerated> + { + self.raw.iter().enumerate().map(IntoIdx { _marker: PhantomData }) + } + + #[inline] + pub fn indices(&self) -> iter::Map, IntoIdx> { + (0..self.len()).map(IntoIdx { _marker: PhantomData }) + } + + #[inline] + pub fn iter_mut(&mut self) -> slice::IterMut<'_, T> { + self.raw.iter_mut() + } + + #[inline] + pub fn iter_enumerated_mut(&mut self) -> Enumerated> + { + self.raw.iter_mut().enumerate().map(IntoIdx { _marker: PhantomData }) + } + + #[inline] + pub fn drain<'a, R: RangeBounds>( + &'a mut self, range: R) -> impl Iterator + 'a { + self.raw.drain(range) + } + + #[inline] + pub fn drain_enumerated<'a, R: RangeBounds>( + &'a mut self, range: R) -> impl Iterator + 'a { + self.raw.drain(range).enumerate().map(IntoIdx { _marker: PhantomData }) + } + + #[inline] + pub fn last(&self) -> Option { + self.len().checked_sub(1).map(I::new) + } + + #[inline] + pub fn shrink_to_fit(&mut self) { + self.raw.shrink_to_fit() + } + + #[inline] + pub fn swap(&mut self, a: I, b: I) { + self.raw.swap(a.index(), b.index()) + } + + #[inline] + pub fn truncate(&mut self, a: usize) { + self.raw.truncate(a) + } + + #[inline] + pub fn get(&self, index: I) -> Option<&T> { + self.raw.get(index.index()) + } + + #[inline] + pub fn get_mut(&mut self, index: I) -> Option<&mut T> { + self.raw.get_mut(index.index()) + } + + /// Returns mutable references to two distinct elements, a and b. Panics if a == b. + #[inline] + pub fn pick2_mut(&mut self, a: I, b: I) -> (&mut T, &mut T) { + let (ai, bi) = (a.index(), b.index()); + assert!(ai != bi); + + if ai < bi { + let (c1, c2) = self.raw.split_at_mut(bi); + (&mut c1[ai], &mut c2[0]) + } else { + let (c2, c1) = self.pick2_mut(b, a); + (c1, c2) + } + } + + pub fn convert_index_type(self) -> IndexVec { + IndexVec { + raw: self.raw, + _marker: PhantomData, + } + } +} + +impl IndexVec { + /// Grows the index vector so that it contains an entry for + /// `elem`; if that is already true, then has no + /// effect. Otherwise, inserts new values as needed by invoking + /// `fill_value`. + #[inline] + pub fn ensure_contains_elem(&mut self, elem: I, fill_value: impl FnMut() -> T) { + let min_new_len = elem.index() + 1; + if self.len() < min_new_len { + self.raw.resize_with(min_new_len, fill_value); + } + } + + #[inline] + pub fn resize(&mut self, new_len: usize, value: T) { + self.raw.resize(new_len, value) + } + + #[inline] + pub fn resize_to_elem(&mut self, elem: I, fill_value: impl FnMut() -> T) { + let min_new_len = elem.index() + 1; + self.raw.resize_with(min_new_len, fill_value); + } +} + +impl IndexVec { + #[inline] + pub fn binary_search(&self, value: &T) -> Result { + match self.raw.binary_search(value) { + Ok(i) => Ok(Idx::new(i)), + Err(i) => Err(Idx::new(i)), + } + } +} + +impl Index for IndexVec { + type Output = T; + + #[inline] + fn index(&self, index: I) -> &T { + &self.raw[index.index()] + } +} + +impl IndexMut for IndexVec { + #[inline] + fn index_mut(&mut self, index: I) -> &mut T { + &mut self.raw[index.index()] + } +} + +impl Default for IndexVec { + #[inline] + fn default() -> Self { + Self::new() + } +} + +impl Extend for IndexVec { + #[inline] + fn extend>(&mut self, iter: J) { + self.raw.extend(iter); + } +} + +impl FromIterator for IndexVec { + #[inline] + fn from_iter(iter: J) -> Self where J: IntoIterator { + IndexVec { raw: FromIterator::from_iter(iter), _marker: PhantomData } + } +} + +impl IntoIterator for IndexVec { + type Item = T; + type IntoIter = vec::IntoIter; + + #[inline] + fn into_iter(self) -> vec::IntoIter { + self.raw.into_iter() + } + +} + +impl<'a, I: Idx, T> IntoIterator for &'a IndexVec { + type Item = &'a T; + type IntoIter = slice::Iter<'a, T>; + + #[inline] + fn into_iter(self) -> slice::Iter<'a, T> { + self.raw.iter() + } +} + +impl<'a, I: Idx, T> IntoIterator for &'a mut IndexVec { + type Item = &'a mut T; + type IntoIter = slice::IterMut<'a, T>; + + #[inline] + fn into_iter(self) -> slice::IterMut<'a, T> { + self.raw.iter_mut() + } +} + +pub struct IntoIdx { _marker: PhantomData } +impl FnOnce<((usize, T),)> for IntoIdx { + type Output = (I, T); + + extern "rust-call" fn call_once(self, ((n, t),): ((usize, T),)) -> Self::Output { + (I::new(n), t) + } +} + +impl FnMut<((usize, T),)> for IntoIdx { + extern "rust-call" fn call_mut(&mut self, ((n, t),): ((usize, T),)) -> Self::Output { + (I::new(n), t) + } +} + +impl FnOnce<(usize,)> for IntoIdx { + type Output = I; + + extern "rust-call" fn call_once(self, (n,): (usize,)) -> Self::Output { + I::new(n) + } +} + +impl FnMut<(usize,)> for IntoIdx { + extern "rust-call" fn call_mut(&mut self, (n,): (usize,)) -> Self::Output { + I::new(n) + } +} diff --git a/src/librustc_lint/Cargo.toml b/src/librustc_lint/Cargo.toml index 041d0aaead9..a61a314d549 100644 --- a/src/librustc_lint/Cargo.toml +++ b/src/librustc_lint/Cargo.toml @@ -15,3 +15,4 @@ rustc_target = { path = "../librustc_target" } syntax = { path = "../libsyntax" } syntax_pos = { path = "../libsyntax_pos" } rustc_data_structures = { path = "../librustc_data_structures" } +rustc_index = { path = "../librustc_index" } diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index 150719c1dbc..3d14a78c33f 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -7,7 +7,7 @@ use rustc::ty::subst::SubstsRef; use rustc::ty::{self, AdtKind, ParamEnv, Ty, TyCtxt}; use rustc::ty::layout::{self, IntegerExt, LayoutOf, VariantIdx, SizeSkeleton}; use rustc::{lint, util}; -use rustc_data_structures::indexed_vec::Idx; +use rustc_index::vec::Idx; use util::nodemap::FxHashSet; use lint::{LateContext, LintContext, LintArray}; use lint::{LintPass, LateLintPass}; diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs index 5bf4067431f..d3619b2f5de 100644 --- a/src/librustc_metadata/cstore.rs +++ b/src/librustc_metadata/cstore.rs @@ -6,7 +6,7 @@ use rustc::hir::def_id::{CrateNum, DefIndex}; use rustc::hir::map::definitions::DefPathTable; use rustc::middle::cstore::{DepKind, ExternCrate, MetadataLoader}; use rustc::mir::interpret::AllocDecodingState; -use rustc_data_structures::indexed_vec::IndexVec; +use rustc_index::vec::IndexVec; use rustc::util::nodemap::{FxHashMap, NodeMap}; use rustc_data_structures::sync::{Lrc, RwLock, Lock}; diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index 3c6a1c47446..9fcc3101545 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -3,7 +3,7 @@ use crate::cstore::{self, CrateMetadata, MetadataBlob, NativeLibrary, ForeignModule}; use crate::schema::*; -use rustc_data_structures::indexed_vec::IndexVec; +use rustc_index::vec::IndexVec; use rustc_data_structures::sync::{Lrc, ReadGuard}; use rustc::hir::map::{DefKey, DefPath, DefPathData, DefPathHash}; use rustc::hir; diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 9beeacbe72d..a86bc283ced 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -8,7 +8,7 @@ use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefIndex, DefId, LocalDefId, use rustc::hir::GenericParamKind; use rustc::hir::map::definitions::DefPathTable; use rustc_data_structures::fingerprint::Fingerprint; -use rustc_data_structures::indexed_vec::IndexVec; +use rustc_index::vec::IndexVec; use rustc::middle::dependency_format::Linkage; use rustc::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel, metadata_symbol_name}; diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs index 4be70c62035..2069adea021 100644 --- a/src/librustc_metadata/schema.rs +++ b/src/librustc_metadata/schema.rs @@ -11,7 +11,7 @@ use rustc::session::CrateDisambiguator; use rustc::session::config::SymbolManglingVersion; use rustc::ty::{self, Ty, ReprOptions}; use rustc_target::spec::{PanicStrategy, TargetTriple}; -use rustc_data_structures::indexed_vec::IndexVec; +use rustc_index::vec::IndexVec; use rustc_data_structures::svh::Svh; use syntax::{ast, attr}; diff --git a/src/librustc_mir/borrow_check/borrow_set.rs b/src/librustc_mir/borrow_check/borrow_set.rs index 3dcd1f56209..7dd1db3b7bd 100644 --- a/src/librustc_mir/borrow_check/borrow_set.rs +++ b/src/librustc_mir/borrow_check/borrow_set.rs @@ -8,7 +8,7 @@ use rustc::mir::visit::{PlaceContext, Visitor, NonUseContext, MutatingUseContext use rustc::mir::{self, Location, Body, Local}; use rustc::ty::{RegionVid, TyCtxt}; use rustc::util::nodemap::{FxHashMap, FxHashSet}; -use rustc_data_structures::indexed_vec::IndexVec; +use rustc_index::vec::IndexVec; use rustc_index::bit_set::BitSet; use std::fmt; use std::ops::Index; diff --git a/src/librustc_mir/borrow_check/conflict_errors.rs b/src/librustc_mir/borrow_check/conflict_errors.rs index 7d5d58ed284..ef459ef0c1b 100644 --- a/src/librustc_mir/borrow_check/conflict_errors.rs +++ b/src/librustc_mir/borrow_check/conflict_errors.rs @@ -7,7 +7,7 @@ use rustc::mir::{ }; use rustc::ty::{self, Ty}; use rustc_data_structures::fx::FxHashSet; -use rustc_data_structures::indexed_vec::Idx; +use rustc_index::vec::Idx; use rustc_errors::{Applicability, DiagnosticBuilder}; use syntax_pos::Span; use syntax::source_map::DesugaringKind; diff --git a/src/librustc_mir/borrow_check/location.rs b/src/librustc_mir/borrow_check/location.rs index cc44dc3f5d4..9e94317b87e 100644 --- a/src/librustc_mir/borrow_check/location.rs +++ b/src/librustc_mir/borrow_check/location.rs @@ -1,5 +1,5 @@ use rustc::mir::{BasicBlock, Location, Body}; -use rustc_data_structures::indexed_vec::{Idx, IndexVec}; +use rustc_index::vec::{Idx, IndexVec}; /// Maps between a MIR Location, which identifies a particular /// statement within a basic block, to a "rich location", which @@ -17,7 +17,7 @@ crate struct LocationTable { statements_before_block: IndexVec, } -newtype_index! { +rustc_index::newtype_index! { pub struct LocationIndex { DEBUG_FORMAT = "LocationIndex({})" } diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index b9009ac5a51..cfa211ad5af 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -21,7 +21,7 @@ use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder}; use rustc_index::bit_set::BitSet; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::graph::dominators::Dominators; -use rustc_data_structures::indexed_vec::IndexVec; +use rustc_index::vec::IndexVec; use smallvec::SmallVec; use std::collections::BTreeMap; diff --git a/src/librustc_mir/borrow_check/mutability_errors.rs b/src/librustc_mir/borrow_check/mutability_errors.rs index d6b91373ab8..8ab4020394f 100644 --- a/src/librustc_mir/borrow_check/mutability_errors.rs +++ b/src/librustc_mir/borrow_check/mutability_errors.rs @@ -5,7 +5,7 @@ use rustc::mir::{ Mutability, Place, PlaceRef, PlaceBase, ProjectionElem, Static, StaticKind }; use rustc::ty::{self, Ty, TyCtxt}; -use rustc_data_structures::indexed_vec::Idx; +use rustc_index::vec::Idx; use syntax_pos::Span; use syntax_pos::symbol::kw; diff --git a/src/librustc_mir/borrow_check/nll/constraints/graph.rs b/src/librustc_mir/borrow_check/nll/constraints/graph.rs index b5630251e58..b6a9a7ee657 100644 --- a/src/librustc_mir/borrow_check/nll/constraints/graph.rs +++ b/src/librustc_mir/borrow_check/nll/constraints/graph.rs @@ -4,7 +4,7 @@ use crate::borrow_check::nll::constraints::{OutlivesConstraintSet, OutlivesConst use rustc::mir::ConstraintCategory; use rustc::ty::RegionVid; use rustc_data_structures::graph; -use rustc_data_structures::indexed_vec::IndexVec; +use rustc_index::vec::IndexVec; use syntax_pos::DUMMY_SP; /// The construct graph organizes the constraints by their end-points. diff --git a/src/librustc_mir/borrow_check/nll/constraints/mod.rs b/src/librustc_mir/borrow_check/nll/constraints/mod.rs index 6121ed0cf0d..93113753c63 100644 --- a/src/librustc_mir/borrow_check/nll/constraints/mod.rs +++ b/src/librustc_mir/borrow_check/nll/constraints/mod.rs @@ -2,7 +2,7 @@ use crate::borrow_check::nll::type_check::Locations; use rustc::mir::ConstraintCategory; use rustc::ty::RegionVid; use rustc_data_structures::graph::scc::Sccs; -use rustc_data_structures::indexed_vec::{Idx, IndexVec}; +use rustc_index::vec::{Idx, IndexVec}; use std::fmt; use std::ops::Index; @@ -100,13 +100,13 @@ impl fmt::Debug for OutlivesConstraint { } } -newtype_index! { +rustc_index::newtype_index! { pub struct OutlivesConstraintIndex { DEBUG_FORMAT = "OutlivesConstraintIndex({})" } } -newtype_index! { +rustc_index::newtype_index! { pub struct ConstraintSccIndex { DEBUG_FORMAT = "ConstraintSccIndex({})" } diff --git a/src/librustc_mir/borrow_check/nll/facts.rs b/src/librustc_mir/borrow_check/nll/facts.rs index f0beb4d3ae3..13e5769c5be 100644 --- a/src/librustc_mir/borrow_check/nll/facts.rs +++ b/src/librustc_mir/borrow_check/nll/facts.rs @@ -4,7 +4,7 @@ use polonius_engine::AllFacts as PoloniusAllFacts; use polonius_engine::Atom; use rustc::mir::Local; use rustc::ty::{RegionVid, TyCtxt}; -use rustc_data_structures::indexed_vec::Idx; +use rustc_index::vec::Idx; use std::error::Error; use std::fmt::Debug; use std::fs::{self, File}; diff --git a/src/librustc_mir/borrow_check/nll/member_constraints.rs b/src/librustc_mir/borrow_check/nll/member_constraints.rs index b5e2e111f38..fd195873a55 100644 --- a/src/librustc_mir/borrow_check/nll/member_constraints.rs +++ b/src/librustc_mir/borrow_check/nll/member_constraints.rs @@ -2,7 +2,7 @@ use crate::rustc::ty::{self, Ty}; use rustc::hir::def_id::DefId; use rustc::infer::region_constraints::MemberConstraint; use rustc_data_structures::fx::FxHashMap; -use rustc_data_structures::indexed_vec::{Idx, IndexVec}; +use rustc_index::vec::{Idx, IndexVec}; use std::hash::Hash; use std::ops::Index; use syntax_pos::Span; @@ -51,7 +51,7 @@ crate struct NllMemberConstraint<'tcx> { end_index: usize, } -newtype_index! { +rustc_index::newtype_index! { crate struct NllMemberConstraintIndex { DEBUG_FORMAT = "MemberConstraintIndex({})" } diff --git a/src/librustc_mir/borrow_check/nll/mod.rs b/src/librustc_mir/borrow_check/nll/mod.rs index 1ff3228afa3..b2e5751b902 100644 --- a/src/librustc_mir/borrow_check/nll/mod.rs +++ b/src/librustc_mir/borrow_check/nll/mod.rs @@ -14,7 +14,7 @@ use rustc::infer::InferCtxt; use rustc::mir::{ClosureOutlivesSubject, ClosureRegionRequirements, Local, Location, Body, LocalKind, BasicBlock, Promoted}; use rustc::ty::{self, RegionKind, RegionVid}; -use rustc_data_structures::indexed_vec::IndexVec; +use rustc_index::vec::IndexVec; use rustc_errors::Diagnostic; use std::fmt::Debug; use std::env; diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs index e29e9232012..6d3f2e56638 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs @@ -12,7 +12,7 @@ use rustc::infer::InferCtxt; use rustc::infer::NLLRegionVariableOrigin; use rustc::mir::{ConstraintCategory, Location, Body}; use rustc::ty::{self, RegionVid}; -use rustc_data_structures::indexed_vec::IndexVec; +use rustc_index::vec::IndexVec; use rustc_errors::DiagnosticBuilder; use std::collections::VecDeque; use syntax::errors::Applicability; diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/var_name.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/var_name.rs index 750a1324fae..7f0e97c9ae4 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/var_name.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/var_name.rs @@ -3,7 +3,7 @@ use crate::borrow_check::nll::ToRegionVid; use crate::borrow_check::Upvar; use rustc::mir::{Local, Body}; use rustc::ty::{RegionVid, TyCtxt}; -use rustc_data_structures::indexed_vec::Idx; +use rustc_index::vec::Idx; use syntax::source_map::Span; use syntax_pos::symbol::Symbol; diff --git a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs index 030839cdb7e..38df8035397 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs @@ -32,7 +32,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::graph::WithSuccessors; use rustc_data_structures::graph::scc::Sccs; use rustc_data_structures::graph::vec_graph::VecGraph; -use rustc_data_structures::indexed_vec::IndexVec; +use rustc_index::vec::IndexVec; use rustc_errors::{Diagnostic, DiagnosticBuilder}; use syntax_pos::Span; diff --git a/src/librustc_mir/borrow_check/nll/region_infer/values.rs b/src/librustc_mir/borrow_check/nll/region_infer/values.rs index 4a56af09d88..6acbff76bdc 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/values.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/values.rs @@ -2,8 +2,8 @@ use rustc::mir::{BasicBlock, Location, Body}; use rustc::ty::{self, RegionVid}; use rustc_index::bit_set::{HybridBitSet, SparseBitMatrix}; use rustc_data_structures::fx::FxHashMap; -use rustc_data_structures::indexed_vec::Idx; -use rustc_data_structures::indexed_vec::IndexVec; +use rustc_index::vec::Idx; +use rustc_index::vec::IndexVec; use std::fmt::Debug; use std::rc::Rc; @@ -116,13 +116,13 @@ impl RegionValueElements { } } -newtype_index! { +rustc_index::newtype_index! { /// A single integer representing a `Location` in the MIR control-flow /// graph. Constructed efficiently from `RegionValueElements`. pub struct PointIndex { DEBUG_FORMAT = "PointIndex({})" } } -newtype_index! { +rustc_index::newtype_index! { /// A single integer representing a `ty::Placeholder`. pub struct PlaceholderIndex { DEBUG_FORMAT = "PlaceholderIndex({})" } } diff --git a/src/librustc_mir/borrow_check/nll/renumber.rs b/src/librustc_mir/borrow_check/nll/renumber.rs index c479c38f30c..cd13803875b 100644 --- a/src/librustc_mir/borrow_check/nll/renumber.rs +++ b/src/librustc_mir/borrow_check/nll/renumber.rs @@ -3,7 +3,7 @@ use rustc::ty::{self, ClosureSubsts, GeneratorSubsts, Ty, TypeFoldable}; use rustc::mir::{Location, Body, Promoted}; use rustc::mir::visit::{MutVisitor, TyContext}; use rustc::infer::{InferCtxt, NLLRegionVariableOrigin}; -use rustc_data_structures::indexed_vec::IndexVec; +use rustc_index::vec::IndexVec; /// Replaces all free regions appearing in the MIR with fresh /// inference variables, returning the number of variables created. diff --git a/src/librustc_mir/borrow_check/nll/type_check/input_output.rs b/src/librustc_mir/borrow_check/nll/type_check/input_output.rs index 99661b1f737..d74dd0fc0f5 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/input_output.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/input_output.rs @@ -12,7 +12,7 @@ use rustc::infer::LateBoundRegionConversionTime; use rustc::mir::*; use rustc::ty::Ty; -use rustc_data_structures::indexed_vec::Idx; +use rustc_index::vec::Idx; use syntax_pos::Span; use super::{Locations, TypeChecker}; diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness/local_use_map.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness/local_use_map.rs index 049d83bb22f..7689ece7066 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/liveness/local_use_map.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/liveness/local_use_map.rs @@ -2,7 +2,7 @@ use crate::borrow_check::nll::region_infer::values::{PointIndex, RegionValueElem use crate::util::liveness::{categorize, DefUse}; use rustc::mir::visit::{PlaceContext, Visitor}; use rustc::mir::{Body, Local, Location}; -use rustc_data_structures::indexed_vec::{Idx, IndexVec}; +use rustc_index::vec::{Idx, IndexVec}; use rustc_data_structures::vec_linked_list as vll; /// A map that cross references each local with the locations where it @@ -44,7 +44,7 @@ struct Appearance { next: Option, } -newtype_index! { +rustc_index::newtype_index! { pub struct AppearanceIndex { .. } } diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs index fa326062fe2..b24ba596d7e 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -43,7 +43,7 @@ use rustc::ty::{ UserTypeAnnotationIndex, }; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_data_structures::indexed_vec::{IndexVec, Idx}; +use rustc_index::vec::{IndexVec, Idx}; use rustc::ty::layout::VariantIdx; use std::rc::Rc; use std::{fmt, iter, mem}; diff --git a/src/librustc_mir/borrow_check/nll/universal_regions.rs b/src/librustc_mir/borrow_check/nll/universal_regions.rs index 7053bdca259..b4470582b71 100644 --- a/src/librustc_mir/borrow_check/nll/universal_regions.rs +++ b/src/librustc_mir/borrow_check/nll/universal_regions.rs @@ -21,7 +21,7 @@ use rustc::ty::fold::TypeFoldable; use rustc::ty::subst::{InternalSubsts, SubstsRef, Subst}; use rustc::ty::{self, ClosureSubsts, GeneratorSubsts, RegionVid, Ty, TyCtxt}; use rustc::util::nodemap::FxHashMap; -use rustc_data_structures::indexed_vec::{Idx, IndexVec}; +use rustc_index::vec::{Idx, IndexVec}; use rustc_errors::DiagnosticBuilder; use std::iter; diff --git a/src/librustc_mir/build/expr/as_place.rs b/src/librustc_mir/build/expr/as_place.rs index 09b33c6654a..17308119339 100644 --- a/src/librustc_mir/build/expr/as_place.rs +++ b/src/librustc_mir/build/expr/as_place.rs @@ -8,7 +8,7 @@ use rustc::mir::interpret::{PanicInfo::BoundsCheck}; use rustc::mir::*; use rustc::ty::{CanonicalUserTypeAnnotation, Variance}; -use rustc_data_structures::indexed_vec::Idx; +use rustc_index::vec::Idx; impl<'a, 'tcx> Builder<'a, 'tcx> { /// Compile `expr`, yielding a place that we can move from etc. diff --git a/src/librustc_mir/build/expr/as_rvalue.rs b/src/librustc_mir/build/expr/as_rvalue.rs index 7dfe98cbebf..b4d93a4493f 100644 --- a/src/librustc_mir/build/expr/as_rvalue.rs +++ b/src/librustc_mir/build/expr/as_rvalue.rs @@ -1,7 +1,7 @@ //! See docs in `build/expr/mod.rs`. use rustc_data_structures::fx::FxHashMap; -use rustc_data_structures::indexed_vec::Idx; +use rustc_index::vec::Idx; use crate::build::expr::category::{Category, RvalueFunc}; use crate::build::{BlockAnd, BlockAndExtension, Builder}; diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index 17932ae8557..9c30d950990 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -14,7 +14,7 @@ use rustc::ty::{self, Ty, TyCtxt}; use rustc::ty::subst::Subst; use rustc::util::nodemap::HirIdMap; use rustc_target::spec::PanicStrategy; -use rustc_data_structures::indexed_vec::{IndexVec, Idx}; +use rustc_index::vec::{IndexVec, Idx}; use std::u32; use rustc_target::spec::abi::Abi; use syntax::attr::{self, UnwindAttr}; @@ -455,7 +455,7 @@ struct CFG<'tcx> { basic_blocks: IndexVec>, } -newtype_index! { +rustc_index::newtype_index! { pub struct ScopeId { .. } } diff --git a/src/librustc_mir/dataflow/generic.rs b/src/librustc_mir/dataflow/generic.rs index 10d0627a9fb..6f598469e9d 100644 --- a/src/librustc_mir/dataflow/generic.rs +++ b/src/librustc_mir/dataflow/generic.rs @@ -21,7 +21,7 @@ use std::ops; use rustc::mir::{self, traversal, BasicBlock, Location}; use rustc_index::bit_set::BitSet; -use rustc_data_structures::indexed_vec::{Idx, IndexVec}; +use rustc_index::vec::{Idx, IndexVec}; use rustc_data_structures::work_queue::WorkQueue; use crate::dataflow::BottomValue; diff --git a/src/librustc_mir/dataflow/impls/borrows.rs b/src/librustc_mir/dataflow/impls/borrows.rs index 44f6c263fed..5e64144df2c 100644 --- a/src/librustc_mir/dataflow/impls/borrows.rs +++ b/src/librustc_mir/dataflow/impls/borrows.rs @@ -7,7 +7,7 @@ use rustc::ty::RegionVid; use rustc_index::bit_set::BitSet; use rustc_data_structures::fx::FxHashMap; -use rustc_data_structures::indexed_vec::{Idx, IndexVec}; +use rustc_index::vec::{Idx, IndexVec}; use crate::dataflow::{BitDenotation, BottomValue, GenKillSet}; use crate::borrow_check::nll::region_infer::RegionInferenceContext; @@ -16,7 +16,7 @@ use crate::borrow_check::places_conflict; use std::rc::Rc; -newtype_index! { +rustc_index::newtype_index! { pub struct BorrowIndex { DEBUG_FORMAT = "bw{}" } diff --git a/src/librustc_mir/dataflow/impls/indirect_mutation.rs b/src/librustc_mir/dataflow/impls/indirect_mutation.rs index 7d20248ebd1..535b803b85f 100644 --- a/src/librustc_mir/dataflow/impls/indirect_mutation.rs +++ b/src/librustc_mir/dataflow/impls/indirect_mutation.rs @@ -1,7 +1,7 @@ use rustc::mir::visit::Visitor; use rustc::mir::{self, Local, Location}; use rustc::ty::{self, TyCtxt}; -use rustc_data_structures::bit_set::BitSet; +use rustc_index::bit_set::BitSet; use syntax_pos::DUMMY_SP; use crate::dataflow::{self, GenKillSet}; diff --git a/src/librustc_mir/dataflow/impls/mod.rs b/src/librustc_mir/dataflow/impls/mod.rs index ee33e9d47ab..6f860d00a22 100644 --- a/src/librustc_mir/dataflow/impls/mod.rs +++ b/src/librustc_mir/dataflow/impls/mod.rs @@ -5,7 +5,7 @@ use rustc::ty::TyCtxt; use rustc::mir::{self, Body, Location}; use rustc_index::bit_set::BitSet; -use rustc_data_structures::indexed_vec::Idx; +use rustc_index::vec::Idx; use super::MoveDataParamEnv; diff --git a/src/librustc_mir/dataflow/mod.rs b/src/librustc_mir/dataflow/mod.rs index 09362e31795..06999abdc8b 100644 --- a/src/librustc_mir/dataflow/mod.rs +++ b/src/librustc_mir/dataflow/mod.rs @@ -2,7 +2,7 @@ use syntax::ast::{self, MetaItem}; use syntax::symbol::{Symbol, sym}; use rustc_index::bit_set::{BitSet, HybridBitSet}; -use rustc_data_structures::indexed_vec::Idx; +use rustc_index::vec::Idx; use rustc_data_structures::work_queue::WorkQueue; use rustc::hir::def_id::DefId; diff --git a/src/librustc_mir/dataflow/move_paths/builder.rs b/src/librustc_mir/dataflow/move_paths/builder.rs index d9119253cae..53b18e4364b 100644 --- a/src/librustc_mir/dataflow/move_paths/builder.rs +++ b/src/librustc_mir/dataflow/move_paths/builder.rs @@ -1,7 +1,7 @@ use rustc::mir::tcx::RvalueInitializationState; use rustc::mir::*; use rustc::ty::{self, TyCtxt}; -use rustc_data_structures::indexed_vec::IndexVec; +use rustc_index::vec::IndexVec; use smallvec::{smallvec, SmallVec}; use std::collections::hash_map::Entry; diff --git a/src/librustc_mir/dataflow/move_paths/mod.rs b/src/librustc_mir/dataflow/move_paths/mod.rs index 156c19c6363..f5a03316d80 100644 --- a/src/librustc_mir/dataflow/move_paths/mod.rs +++ b/src/librustc_mir/dataflow/move_paths/mod.rs @@ -2,7 +2,7 @@ use core::slice::Iter; use rustc::mir::*; use rustc::ty::{Ty, TyCtxt}; use rustc::util::nodemap::FxHashMap; -use rustc_data_structures::indexed_vec::{Enumerated, Idx, IndexVec}; +use rustc_index::vec::{Enumerated, Idx, IndexVec}; use smallvec::SmallVec; use syntax_pos::Span; @@ -13,19 +13,19 @@ use self::abs_domain::{AbstractElem, Lift}; mod abs_domain; -newtype_index! { +rustc_index::newtype_index! { pub struct MovePathIndex { DEBUG_FORMAT = "mp{}" } } -newtype_index! { +rustc_index::newtype_index! { pub struct MoveOutIndex { DEBUG_FORMAT = "mo{}" } } -newtype_index! { +rustc_index::newtype_index! { pub struct InitIndex { DEBUG_FORMAT = "in{}" } diff --git a/src/librustc_mir/hair/cx/block.rs b/src/librustc_mir/hair/cx/block.rs index 33d67dcf914..e9777dab26e 100644 --- a/src/librustc_mir/hair/cx/block.rs +++ b/src/librustc_mir/hair/cx/block.rs @@ -5,7 +5,7 @@ use rustc::middle::region; use rustc::hir; use rustc::ty; -use rustc_data_structures::indexed_vec::Idx; +use rustc_index::vec::Idx; impl<'tcx> Mirror<'tcx> for &'tcx hir::Block { type Output = Block<'tcx>; diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index eed51cdab8c..db314cb5faf 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -3,7 +3,7 @@ use crate::hair::cx::Cx; use crate::hair::cx::block; use crate::hair::cx::to_ref::ToRef; use crate::hair::util::UserAnnotatedTyHelpers; -use rustc_data_structures::indexed_vec::Idx; +use rustc_index::vec::Idx; use rustc::hir::def::{CtorOf, Res, DefKind, CtorKind}; use rustc::mir::interpret::{GlobalId, ErrorHandled, ConstValue}; use rustc::ty::{self, AdtKind, Ty}; diff --git a/src/librustc_mir/hair/cx/mod.rs b/src/librustc_mir/hair/cx/mod.rs index 32efbd6f011..e120b496d3d 100644 --- a/src/librustc_mir/hair/cx/mod.rs +++ b/src/librustc_mir/hair/cx/mod.rs @@ -5,7 +5,7 @@ use crate::hair::*; use crate::hair::util::UserAnnotatedTyHelpers; -use rustc_data_structures::indexed_vec::Idx; +use rustc_index::vec::Idx; use rustc::hir::def_id::DefId; use rustc::hir::Node; use rustc::middle::region; diff --git a/src/librustc_mir/hair/pattern/_match.rs b/src/librustc_mir/hair/pattern/_match.rs index 75a84f6ec64..d3bc61a4dde 100644 --- a/src/librustc_mir/hair/pattern/_match.rs +++ b/src/librustc_mir/hair/pattern/_match.rs @@ -161,7 +161,7 @@ use self::Usefulness::*; use self::WitnessPreference::*; use rustc_data_structures::fx::FxHashMap; -use rustc_data_structures::indexed_vec::Idx; +use rustc_index::vec::Idx; use super::{FieldPat, Pat, PatKind, PatRange}; use super::{PatternFoldable, PatternFolder, compare_const_vals}; diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs index 4d2fee3d160..3793f7c1075 100644 --- a/src/librustc_mir/hair/pattern/mod.rs +++ b/src/librustc_mir/hair/pattern/mod.rs @@ -24,7 +24,7 @@ use rustc::hir::def::{CtorOf, Res, DefKind, CtorKind}; use rustc::hir::pat_util::EnumerateAndAdjustIterator; use rustc::hir::ptr::P; -use rustc_data_structures::indexed_vec::Idx; +use rustc_index::vec::Idx; use rustc_data_structures::fx::FxHashSet; use std::cmp::Ordering; diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index fdf85260c3d..e1c45132103 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -12,7 +12,7 @@ use rustc::ty::layout::{ use rustc::ty::subst::SubstsRef; use rustc::ty::{self, Ty, TyCtxt, TypeFoldable}; use rustc::ty::query::TyCtxtAt; -use rustc_data_structures::indexed_vec::IndexVec; +use rustc_index::vec::IndexVec; use rustc::mir::interpret::{ GlobalId, Scalar, Pointer, FrameInfo, AllocId, InterpResult, truncate, sign_extend, diff --git a/src/librustc_mir/interpret/snapshot.rs b/src/librustc_mir/interpret/snapshot.rs index 4c7d0dcb697..7ce151e087a 100644 --- a/src/librustc_mir/interpret/snapshot.rs +++ b/src/librustc_mir/interpret/snapshot.rs @@ -17,7 +17,7 @@ use rustc::mir::interpret::{ use rustc::ty::{self, TyCtxt}; use rustc::ty::layout::{Align, Size}; use rustc_data_structures::fx::FxHashSet; -use rustc_data_structures::indexed_vec::IndexVec; +use rustc_index::vec::IndexVec; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use syntax::ast::Mutability; use syntax::source_map::Span; diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs index 4fae0976ffb..7303880602e 100644 --- a/src/librustc_mir/shim.rs +++ b/src/librustc_mir/shim.rs @@ -6,7 +6,7 @@ use rustc::ty::layout::VariantIdx; use rustc::ty::subst::{Subst, InternalSubsts}; use rustc::ty::query::Providers; -use rustc_data_structures::indexed_vec::{IndexVec, Idx}; +use rustc_index::vec::{IndexVec, Idx}; use rustc_target::spec::abi::Abi; use syntax_pos::{Span, sym}; diff --git a/src/librustc_mir/transform/add_call_guards.rs b/src/librustc_mir/transform/add_call_guards.rs index 15ecc6c3792..bf3df1ae2fd 100644 --- a/src/librustc_mir/transform/add_call_guards.rs +++ b/src/librustc_mir/transform/add_call_guards.rs @@ -1,6 +1,6 @@ use rustc::ty::TyCtxt; use rustc::mir::*; -use rustc_data_structures::indexed_vec::{Idx, IndexVec}; +use rustc_index::vec::{Idx, IndexVec}; use crate::transform::{MirPass, MirSource}; #[derive(PartialEq)] diff --git a/src/librustc_mir/transform/check_consts/qualifs.rs b/src/librustc_mir/transform/check_consts/qualifs.rs index d9d0ce18555..0c6468309dc 100644 --- a/src/librustc_mir/transform/check_consts/qualifs.rs +++ b/src/librustc_mir/transform/check_consts/qualifs.rs @@ -3,7 +3,7 @@ use rustc::mir::*; use rustc::mir::interpret::ConstValue; use rustc::ty::{self, Ty}; -use rustc_data_structures::bit_set::BitSet; +use rustc_index::bit_set::BitSet; use syntax_pos::DUMMY_SP; use super::Item as ConstCx; diff --git a/src/librustc_mir/transform/check_consts/resolver.rs b/src/librustc_mir/transform/check_consts/resolver.rs index 2789693ecb6..f95b240195b 100644 --- a/src/librustc_mir/transform/check_consts/resolver.rs +++ b/src/librustc_mir/transform/check_consts/resolver.rs @@ -5,7 +5,7 @@ use rustc::mir::visit::Visitor; use rustc::mir::{self, BasicBlock, Local, Location}; -use rustc_data_structures::bit_set::BitSet; +use rustc_index::bit_set::BitSet; use std::cell::RefCell; use std::marker::PhantomData; diff --git a/src/librustc_mir/transform/check_consts/validation.rs b/src/librustc_mir/transform/check_consts/validation.rs index 7e876dd1d99..e74b22b4352 100644 --- a/src/librustc_mir/transform/check_consts/validation.rs +++ b/src/librustc_mir/transform/check_consts/validation.rs @@ -5,7 +5,7 @@ use rustc::mir::visit::{PlaceContext, Visitor, MutatingUseContext, NonMutatingUs use rustc::mir::*; use rustc::ty::cast::CastTy; use rustc::ty::{self, TyCtxt}; -use rustc_data_structures::bit_set::BitSet; +use rustc_index::bit_set::BitSet; use rustc_target::spec::abi::Abi; use syntax::symbol::sym; use syntax_pos::Span; diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs index acd53ac68ae..70855d70228 100644 --- a/src/librustc_mir/transform/check_unsafety.rs +++ b/src/librustc_mir/transform/check_unsafety.rs @@ -1,5 +1,5 @@ use rustc_data_structures::fx::FxHashSet; -use rustc_data_structures::indexed_vec::IndexVec; +use rustc_index::vec::IndexVec; use rustc_data_structures::sync::Lrc; use rustc::ty::query::Providers; diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 612822b6d9d..f34bfbeab3b 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -21,7 +21,7 @@ use syntax::ast::Mutability; use syntax_pos::{Span, DUMMY_SP}; use rustc::ty::subst::InternalSubsts; use rustc_data_structures::fx::FxHashMap; -use rustc_data_structures::indexed_vec::IndexVec; +use rustc_index::vec::IndexVec; use rustc::ty::layout::{ LayoutOf, TyLayout, LayoutError, HasTyCtxt, TargetDataLayout, HasDataLayout, }; diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs index 649665b4aba..bfc5eb5a94e 100644 --- a/src/librustc_mir/transform/generator.rs +++ b/src/librustc_mir/transform/generator.rs @@ -58,7 +58,7 @@ use rustc::ty::GeneratorSubsts; use rustc::ty::layout::VariantIdx; use rustc::ty::subst::SubstsRef; use rustc_data_structures::fx::FxHashMap; -use rustc_data_structures::indexed_vec::{Idx, IndexVec}; +use rustc_index::vec::{Idx, IndexVec}; use rustc_index::bit_set::{BitSet, BitMatrix}; use std::borrow::Cow; use std::iter; diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs index f4c522245f7..9830ed35ffc 100644 --- a/src/librustc_mir/transform/inline.rs +++ b/src/librustc_mir/transform/inline.rs @@ -4,7 +4,7 @@ use rustc::hir::CodegenFnAttrFlags; use rustc::hir::def_id::DefId; use rustc_index::bit_set::BitSet; -use rustc_data_structures::indexed_vec::{Idx, IndexVec}; +use rustc_index::vec::{Idx, IndexVec}; use rustc::mir::*; use rustc::mir::visit::*; diff --git a/src/librustc_mir/transform/instcombine.rs b/src/librustc_mir/transform/instcombine.rs index 6b609e25ec0..bb98d63b1ee 100644 --- a/src/librustc_mir/transform/instcombine.rs +++ b/src/librustc_mir/transform/instcombine.rs @@ -5,7 +5,7 @@ use rustc::mir::{Constant, Location, Place, PlaceBase, Body, Operand, Projection use rustc::mir::visit::{MutVisitor, Visitor}; use rustc::ty::{self, TyCtxt}; use rustc::util::nodemap::{FxHashMap, FxHashSet}; -use rustc_data_structures::indexed_vec::Idx; +use rustc_index::vec::Idx; use std::mem; use crate::transform::{MirPass, MirSource}; diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs index 5037c791cb6..7e06729c2c7 100644 --- a/src/librustc_mir/transform/mod.rs +++ b/src/librustc_mir/transform/mod.rs @@ -1,5 +1,5 @@ use crate::{build, shim}; -use rustc_data_structures::indexed_vec::IndexVec; +use rustc_index::vec::IndexVec; use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; use rustc::mir::{Body, MirPhase, Promoted}; use rustc::ty::{TyCtxt, InstanceDef}; diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs index 7d1b96b8be1..5d241ffe1c0 100644 --- a/src/librustc_mir/transform/promote_consts.rs +++ b/src/librustc_mir/transform/promote_consts.rs @@ -20,7 +20,7 @@ use rustc::ty::subst::InternalSubsts; use rustc::ty::TyCtxt; use syntax_pos::Span; -use rustc_data_structures::indexed_vec::{IndexVec, Idx}; +use rustc_index::vec::{IndexVec, Idx}; use std::{iter, mem, usize}; diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index ee7b0cada12..2fa6b9d1a29 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -5,7 +5,7 @@ //! diagnostics as to why a constant rvalue wasn't promoted. use rustc_index::bit_set::BitSet; -use rustc_data_structures::indexed_vec::IndexVec; +use rustc_index::vec::IndexVec; use rustc_data_structures::fx::FxHashSet; use rustc_target::spec::abi::Abi; use rustc::hir; diff --git a/src/librustc_mir/transform/simplify.rs b/src/librustc_mir/transform/simplify.rs index c6df9d49ec0..9ffff9a92fa 100644 --- a/src/librustc_mir/transform/simplify.rs +++ b/src/librustc_mir/transform/simplify.rs @@ -28,7 +28,7 @@ //! return. use rustc_index::bit_set::BitSet; -use rustc_data_structures::indexed_vec::{Idx, IndexVec}; +use rustc_index::vec::{Idx, IndexVec}; use rustc::ty::TyCtxt; use rustc::mir::*; use rustc::mir::visit::{MutVisitor, Visitor, PlaceContext}; diff --git a/src/librustc_mir/transform/uniform_array_move_out.rs b/src/librustc_mir/transform/uniform_array_move_out.rs index eb61cd2f657..efa39d91205 100644 --- a/src/librustc_mir/transform/uniform_array_move_out.rs +++ b/src/librustc_mir/transform/uniform_array_move_out.rs @@ -30,7 +30,7 @@ use rustc::ty; use rustc::ty::TyCtxt; use rustc::mir::*; use rustc::mir::visit::{Visitor, PlaceContext, NonUseContext}; -use rustc_data_structures::indexed_vec::{IndexVec}; +use rustc_index::vec::{IndexVec}; use crate::transform::{MirPass, MirSource}; use crate::util::patch::MirPatch; diff --git a/src/librustc_mir/util/aggregate.rs b/src/librustc_mir/util/aggregate.rs index b3565d40b8e..c0f92185745 100644 --- a/src/librustc_mir/util/aggregate.rs +++ b/src/librustc_mir/util/aggregate.rs @@ -1,7 +1,7 @@ use rustc::mir::*; use rustc::ty::Ty; use rustc::ty::layout::VariantIdx; -use rustc_data_structures::indexed_vec::Idx; +use rustc_index::vec::Idx; use std::iter::TrustedLen; diff --git a/src/librustc_mir/util/def_use.rs b/src/librustc_mir/util/def_use.rs index 59821440c66..3aea25fa876 100644 --- a/src/librustc_mir/util/def_use.rs +++ b/src/librustc_mir/util/def_use.rs @@ -2,7 +2,7 @@ use rustc::mir::{Local, Location, Body}; use rustc::mir::visit::{PlaceContext, MutVisitor, Visitor}; -use rustc_data_structures::indexed_vec::IndexVec; +use rustc_index::vec::IndexVec; use std::mem; pub struct DefUseAnalysis { diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs index e1015edfa8e..37b9398f9cb 100644 --- a/src/librustc_mir/util/elaborate_drops.rs +++ b/src/librustc_mir/util/elaborate_drops.rs @@ -7,7 +7,7 @@ use rustc::ty::{self, Ty, TyCtxt}; use rustc::ty::layout::VariantIdx; use rustc::ty::subst::SubstsRef; use rustc::ty::util::IntTypeExt; -use rustc_data_structures::indexed_vec::Idx; +use rustc_index::vec::Idx; use crate::util::patch::MirPatch; use std::convert::TryInto; diff --git a/src/librustc_mir/util/graphviz.rs b/src/librustc_mir/util/graphviz.rs index 9d142d9b700..7fcb7a40a3c 100644 --- a/src/librustc_mir/util/graphviz.rs +++ b/src/librustc_mir/util/graphviz.rs @@ -1,7 +1,7 @@ use rustc::hir::def_id::DefId; use rustc::mir::*; use rustc::ty::TyCtxt; -use rustc_data_structures::indexed_vec::Idx; +use rustc_index::vec::Idx; use std::fmt::Debug; use std::io::{self, Write}; diff --git a/src/librustc_mir/util/liveness.rs b/src/librustc_mir/util/liveness.rs index 24ee803c9f8..9757f4ac392 100644 --- a/src/librustc_mir/util/liveness.rs +++ b/src/librustc_mir/util/liveness.rs @@ -31,7 +31,7 @@ use rustc::mir::Local; use rustc::mir::*; use rustc::ty::{self, TyCtxt}; use rustc_index::bit_set::BitSet; -use rustc_data_structures::indexed_vec::{Idx, IndexVec}; +use rustc_index::vec::{Idx, IndexVec}; use rustc_data_structures::work_queue::WorkQueue; use std::fs; use std::io::{self, Write}; diff --git a/src/librustc_mir/util/patch.rs b/src/librustc_mir/util/patch.rs index 2ea9924af7f..a5f7e540157 100644 --- a/src/librustc_mir/util/patch.rs +++ b/src/librustc_mir/util/patch.rs @@ -1,6 +1,6 @@ use rustc::ty::Ty; use rustc::mir::*; -use rustc_data_structures::indexed_vec::{IndexVec, Idx}; +use rustc_index::vec::{IndexVec, Idx}; use syntax_pos::Span; /// This struct represents a patch to MIR, which can add diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs index c35c9e4da9f..7f6b60b1b11 100644 --- a/src/librustc_mir/util/pretty.rs +++ b/src/librustc_mir/util/pretty.rs @@ -3,7 +3,7 @@ use rustc::mir::*; use rustc::mir::visit::Visitor; use rustc::ty::{self, TyCtxt}; use rustc_data_structures::fx::FxHashMap; -use rustc_data_structures::indexed_vec::Idx; +use rustc_index::vec::Idx; use std::fmt::Display; use std::fmt::Write as _; use std::fs; diff --git a/src/librustc_target/Cargo.toml b/src/librustc_target/Cargo.toml index cab1e0e0137..fba2ea02bb4 100644 --- a/src/librustc_target/Cargo.toml +++ b/src/librustc_target/Cargo.toml @@ -14,3 +14,4 @@ log = "0.4" rustc_data_structures = { path = "../librustc_data_structures" } rustc_serialize = { path = "../libserialize", package = "serialize" } syntax_pos = { path = "../libsyntax_pos" } +rustc_index = { path = "../librustc_index" } diff --git a/src/librustc_target/abi/mod.rs b/src/librustc_target/abi/mod.rs index dafa8661176..26d37f196be 100644 --- a/src/librustc_target/abi/mod.rs +++ b/src/librustc_target/abi/mod.rs @@ -6,8 +6,7 @@ use crate::spec::Target; use std::fmt; use std::ops::{Add, Deref, Sub, Mul, AddAssign, Range, RangeInclusive}; -use rustc_data_structures::newtype_index; -use rustc_data_structures::indexed_vec::{Idx, IndexVec}; +use rustc_index::vec::{Idx, IndexVec}; use syntax_pos::symbol::{sym, Symbol}; use syntax_pos::Span; @@ -844,7 +843,7 @@ impl Abi { } } -newtype_index! { +rustc_index::newtype_index! { pub struct VariantIdx { .. } } diff --git a/src/librustc_typeck/Cargo.toml b/src/librustc_typeck/Cargo.toml index ac396667683..a6644258be2 100644 --- a/src/librustc_typeck/Cargo.toml +++ b/src/librustc_typeck/Cargo.toml @@ -20,3 +20,4 @@ rustc_target = { path = "../librustc_target" } smallvec = { version = "0.6.7", features = ["union", "may_dangle"] } syntax = { path = "../libsyntax" } syntax_pos = { path = "../libsyntax_pos" } +rustc_index = { path = "../librustc_index" } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index a7832b8c2cf..131a33a4512 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -99,7 +99,7 @@ use crate::middle::lang_items; use crate::namespace::Namespace; use rustc::infer::{self, InferCtxt, InferOk, InferResult}; use rustc::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse}; -use rustc_data_structures::indexed_vec::Idx; +use rustc_index::vec::Idx; use rustc_target::spec::abi::Abi; use rustc::infer::opaque_types::OpaqueTypeDecl; use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index b530851b80d..8f35ca01f79 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -9,7 +9,7 @@ mod simplify; mod auto_trait; mod blanket_impl; -use rustc_data_structures::indexed_vec::{IndexVec, Idx}; +use rustc_index::vec::{IndexVec, Idx}; use rustc_target::spec::abi::Abi; use rustc_typeck::hir_ty_to_ty; use rustc::infer::region_constraints::{RegionConstraintData, Constraint}; diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 2985e7f70b5..539bf5dfe28 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -25,6 +25,7 @@ extern crate getopts; extern crate env_logger; extern crate rustc; extern crate rustc_data_structures; +extern crate rustc_index; extern crate rustc_driver; extern crate rustc_resolve; extern crate rustc_lint; diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index bc468c1ad0e..7a5c92167bc 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -14,7 +14,7 @@ use crate::symbol::{kw, sym, Symbol}; use crate::tokenstream::TokenStream; use crate::ThinVec; -use rustc_data_structures::indexed_vec::Idx; +use rustc_index::vec::Idx; #[cfg(target_arch = "x86_64")] use rustc_data_structures::static_assert_size; use rustc_target::spec::abi::Abi; @@ -241,9 +241,8 @@ impl ParenthesizedArgs { // hack to ensure that we don't try to access the private parts of `NodeId` in this module mod node_id_inner { - use rustc_data_structures::indexed_vec::Idx; - use rustc_data_structures::newtype_index; - newtype_index! { + use rustc_index::vec::Idx; + rustc_index::newtype_index! { pub struct NodeId { ENCODABLE = custom DEBUG_FORMAT = "NodeId({})" diff --git a/src/libsyntax_pos/Cargo.toml b/src/libsyntax_pos/Cargo.toml index bc13d2a1611..378f7a955a3 100644 --- a/src/libsyntax_pos/Cargo.toml +++ b/src/libsyntax_pos/Cargo.toml @@ -13,6 +13,7 @@ doctest = false rustc_serialize = { path = "../libserialize", package = "serialize" } rustc_macros = { path = "../librustc_macros" } rustc_data_structures = { path = "../librustc_data_structures" } +rustc_index = { path = "../librustc_index" } arena = { path = "../libarena" } scoped-tls = "1.0" unicode-width = "0.1.4" diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index 44a34070dec..1769135e7f2 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -4,8 +4,7 @@ use arena::DroplessArena; use rustc_data_structures::fx::FxHashMap; -use rustc_data_structures::indexed_vec::Idx; -use rustc_data_structures::newtype_index; +use rustc_index::vec::Idx; use rustc_macros::symbols; use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; use rustc_serialize::{UseSpecializedDecodable, UseSpecializedEncodable}; @@ -897,15 +896,15 @@ impl UseSpecializedDecodable for Ident { /// ``` /// Internally, a symbol is implemented as an index, and all operations /// (including hashing, equality, and ordering) operate on that index. The use -/// of `newtype_index!` means that `Option` only takes up 4 bytes, -/// because `newtype_index!` reserves the last 256 values for tagging purposes. +/// of `rustc_index::newtype_index!` means that `Option` only takes up 4 bytes, +/// because `rustc_index::newtype_index!` reserves the last 256 values for tagging purposes. /// -/// Note that `Symbol` cannot directly be a `newtype_index!` because it +/// Note that `Symbol` cannot directly be a `rustc_index::newtype_index!` because it /// implements `fmt::Debug`, `Encodable`, and `Decodable` in special ways. #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct Symbol(SymbolIndex); -newtype_index! { +rustc_index::newtype_index! { pub struct SymbolIndex { .. } } diff --git a/src/test/ui-fulldeps/newtype_index.rs b/src/test/ui-fulldeps/newtype_index.rs index 336b584768f..fe68b394e5a 100644 --- a/src/test/ui-fulldeps/newtype_index.rs +++ b/src/test/ui-fulldeps/newtype_index.rs @@ -2,10 +2,10 @@ #![feature(rustc_private)] -extern crate rustc_data_structures; +extern crate rustc_index; extern crate serialize as rustc_serialize; -use rustc_data_structures::{newtype_index, indexed_vec::Idx}; +use rustc_index::{newtype_index, vec::Idx}; newtype_index!(struct MyIdx { MAX = 0xFFFF_FFFA }); -- cgit 1.4.1-3-g733a5