Improve hygiene of newtype_index

Also add unit tests
This commit is contained in:
Matthew Jasper 2020-01-05 15:01:00 +00:00
parent ebbb2bf37a
commit 9462c8babb
13 changed files with 80 additions and 52 deletions

View File

@ -2,7 +2,7 @@
use crate::dep_graph::DepNode;
use crate::ich::Fingerprint;
use rustc_index::vec::{Idx, IndexVec};
use rustc_index::vec::IndexVec;
rustc_index::newtype_index! {
pub struct SerializedDepNodeIndex { .. }

View File

@ -14,7 +14,6 @@ use rustc_hir::Node;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_index::vec::Idx;
use rustc_macros::HashStable;
use rustc_span::{Span, DUMMY_SP};

View File

@ -56,7 +56,6 @@ impl fmt::Display for HirId {
rustc_data_structures::define_id_collections!(HirIdMap, HirIdSet, HirId);
rustc_data_structures::define_id_collections!(ItemLocalMap, ItemLocalSet, ItemLocalId);
use rustc_index::vec::Idx;
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

View File

@ -120,13 +120,13 @@ macro_rules! newtype_index {
impl $type {
$v const MAX_AS_U32: u32 = $max;
$v const MAX: $type = $type::from_u32_const($max);
$v const MAX: Self = Self::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)
Self::from_u32_unchecked(value as u32)
}
}
@ -134,7 +134,7 @@ macro_rules! newtype_index {
$v fn from_u32(value: u32) -> Self {
assert!(value <= $max);
unsafe {
$type::from_u32_unchecked(value)
Self::from_u32_unchecked(value)
}
}
@ -152,13 +152,13 @@ macro_rules! newtype_index {
];
unsafe {
$type { private: value }
Self { private: value }
}
}
#[inline]
$v const unsafe fn from_u32_unchecked(value: u32) -> Self {
$type { private: value }
Self { private: value }
}
/// Extracts the value of this index as an integer.
@ -184,14 +184,14 @@ macro_rules! newtype_index {
type Output = Self;
fn add(self, other: usize) -> Self {
Self::new(self.index() + other)
Self::from_usize(self.index() + other)
}
}
impl Idx for $type {
impl $crate::vec::Idx for $type {
#[inline]
fn new(value: usize) -> Self {
Self::from(value)
Self::from_usize(value)
}
#[inline]
@ -204,39 +204,39 @@ macro_rules! newtype_index {
#[inline]
fn steps_between(start: &Self, end: &Self) -> Option<usize> {
<usize as ::std::iter::Step>::steps_between(
&Idx::index(*start),
&Idx::index(*end),
&Self::index(*start),
&Self::index(*end),
)
}
#[inline]
fn replace_one(&mut self) -> Self {
::std::mem::replace(self, Self::new(1))
::std::mem::replace(self, Self::from_u32(1))
}
#[inline]
fn replace_zero(&mut self) -> Self {
::std::mem::replace(self, Self::new(0))
::std::mem::replace(self, Self::from_u32(0))
}
#[inline]
fn add_one(&self) -> Self {
Self::new(Idx::index(*self) + 1)
Self::from_usize(Self::index(*self) + 1)
}
#[inline]
fn sub_one(&self) -> Self {
Self::new(Idx::index(*self) - 1)
Self::from_usize(Self::index(*self) - 1)
}
#[inline]
fn add_usize(&self, u: usize) -> Option<Self> {
Idx::index(*self).checked_add(u).map(Self::new)
Self::index(*self).checked_add(u).map(Self::from_usize)
}
#[inline]
fn sub_usize(&self, u: usize) -> Option<Self> {
Idx::index(*self).checked_sub(u).map(Self::new)
Self::index(*self).checked_sub(u).map(Self::from_usize)
}
}
@ -257,14 +257,14 @@ macro_rules! newtype_index {
impl From<usize> for $type {
#[inline]
fn from(value: usize) -> Self {
$type::from_usize(value)
Self::from_usize(value)
}
}
impl From<u32> for $type {
#[inline]
fn from(value: u32) -> Self {
$type::from_u32(value)
Self::from_u32(value)
}
}
@ -409,7 +409,7 @@ macro_rules! newtype_index {
(@decodable $type:ident) => (
impl ::rustc_serialize::Decodable for $type {
fn decode<D: ::rustc_serialize::Decoder>(d: &mut D) -> Result<Self, D::Error> {
d.read_u32().map(Self::from)
d.read_u32().map(Self::from_u32)
}
}
);
@ -500,7 +500,7 @@ macro_rules! newtype_index {
const $name:ident = $constant:expr,
$($tokens:tt)*) => (
$(#[doc = $doc])*
pub const $name: $type = $type::from_u32_const($constant);
$v const $name: $type = $type::from_u32_const($constant);
$crate::newtype_index!(
@derives [$($derives,)*]
@attrs [$(#[$attrs])*]
@ -839,3 +839,6 @@ impl<I: Idx> FnMut<(usize,)> for IntoIdx<I> {
I::new(n)
}
}
#[cfg(test)]
mod tests;

View File

@ -0,0 +1,51 @@
#![allow(dead_code)]
newtype_index!(struct MyIdx { MAX = 0xFFFF_FFFA });
#[test]
fn index_size_is_optimized() {
use std::mem::size_of;
assert_eq!(size_of::<MyIdx>(), 4);
// Uses 0xFFFF_FFFB
assert_eq!(size_of::<Option<MyIdx>>(), 4);
// Uses 0xFFFF_FFFC
assert_eq!(size_of::<Option<Option<MyIdx>>>(), 4);
// Uses 0xFFFF_FFFD
assert_eq!(size_of::<Option<Option<Option<MyIdx>>>>(), 4);
// Uses 0xFFFF_FFFE
assert_eq!(size_of::<Option<Option<Option<Option<MyIdx>>>>>(), 4);
// Uses 0xFFFF_FFFF
assert_eq!(size_of::<Option<Option<Option<Option<Option<MyIdx>>>>>>(), 4);
// Uses a tag
assert_eq!(size_of::<Option<Option<Option<Option<Option<Option<MyIdx>>>>>>>(), 8);
}
#[test]
fn range_iterator_iterates_forwards() {
let range = MyIdx::from_u32(1)..MyIdx::from_u32(4);
assert_eq!(
range.collect::<Vec<_>>(),
[MyIdx::from_u32(1), MyIdx::from_u32(2), MyIdx::from_u32(3)]
);
}
#[test]
fn range_iterator_iterates_backwards() {
let range = MyIdx::from_u32(1)..MyIdx::from_u32(4);
assert_eq!(
range.rev().collect::<Vec<_>>(),
[MyIdx::from_u32(3), MyIdx::from_u32(2), MyIdx::from_u32(1)]
);
}
#[test]
fn range_count_is_correct() {
let range = MyIdx::from_u32(1)..MyIdx::from_u32(4);
assert_eq!(range.count(), 3);
}
#[test]
fn range_size_hint_is_correct() {
let range = MyIdx::from_u32(1)..MyIdx::from_u32(4);
assert_eq!(range.size_hint(), (3, Some(3)));
}

View File

@ -1,7 +1,7 @@
use rustc::mir::ConstraintCategory;
use rustc::ty::RegionVid;
use rustc_data_structures::graph::scc::Sccs;
use rustc_index::vec::{Idx, IndexVec};
use rustc_index::vec::IndexVec;
use std::fmt;
use std::ops::Index;

View File

@ -2,7 +2,7 @@ use crate::rustc::ty::{self, Ty};
use rustc::infer::region_constraints::MemberConstraint;
use rustc_data_structures::fx::FxHashMap;
use rustc_hir::def_id::DefId;
use rustc_index::vec::{Idx, IndexVec};
use rustc_index::vec::IndexVec;
use rustc_span::Span;
use std::hash::Hash;
use std::ops::Index;

View File

@ -1,7 +1,7 @@
use rustc::mir::visit::{PlaceContext, Visitor};
use rustc::mir::{Local, Location, ReadOnlyBodyAndCache};
use rustc_data_structures::vec_linked_list as vll;
use rustc_index::vec::{Idx, IndexVec};
use rustc_index::vec::IndexVec;
use crate::util::liveness::{categorize, DefUse};

View File

@ -4,7 +4,7 @@ use rustc::ty::{self, TyCtxt};
use rustc_data_structures::fx::FxHashMap;
use rustc_index::bit_set::BitSet;
use rustc_index::vec::{Idx, IndexVec};
use rustc_index::vec::IndexVec;
use crate::borrow_check::{
places_conflict, BorrowData, BorrowSet, PlaceConflictBias, PlaceExt, RegionInferenceContext,

View File

@ -2,7 +2,7 @@ use core::slice::Iter;
use rustc::mir::*;
use rustc::ty::{ParamEnv, Ty, TyCtxt};
use rustc_data_structures::fx::FxHashMap;
use rustc_index::vec::{Enumerated, Idx, IndexVec};
use rustc_index::vec::{Enumerated, IndexVec};
use rustc_span::Span;
use smallvec::SmallVec;

View File

@ -1,4 +1,3 @@
use rustc_index::vec::Idx;
use rustc_serialize::{Decoder, Encoder};
use rustc_span::ExpnId;
use std::fmt;

View File

@ -5,7 +5,6 @@
use arena::DroplessArena;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
use rustc_index::vec::Idx;
use rustc_macros::{symbols, HashStable_Generic};
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
use rustc_serialize::{UseSpecializedDecodable, UseSpecializedEncodable};

View File

@ -1,22 +0,0 @@
// run-pass
#![feature(rustc_private)]
extern crate rustc_index;
extern crate serialize as rustc_serialize;
use rustc_index::{newtype_index, vec::Idx};
newtype_index!(struct MyIdx { MAX = 0xFFFF_FFFA });
use std::mem::size_of;
fn main() {
assert_eq!(size_of::<MyIdx>(), 4);
assert_eq!(size_of::<Option<MyIdx>>(), 4);
assert_eq!(size_of::<Option<Option<MyIdx>>>(), 4);
assert_eq!(size_of::<Option<Option<Option<MyIdx>>>>(), 4);
assert_eq!(size_of::<Option<Option<Option<Option<MyIdx>>>>>(), 4);
assert_eq!(size_of::<Option<Option<Option<Option<Option<MyIdx>>>>>>(), 4);
assert_eq!(size_of::<Option<Option<Option<Option<Option<Option<MyIdx>>>>>>>(), 8);
}