make UniverseIndex hashable, rename "sub-" to "superuniverse"

The only name was silly. U1 can contain everything from U0 *plus* more
things.
This commit is contained in:
Niko Matsakis 2018-09-26 12:27:01 -04:00
parent 28df2bf7b5
commit 460915be73
7 changed files with 28 additions and 25 deletions

View file

@ -593,7 +593,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
where
T : TypeFoldable<'tcx>,
{
let new_universe = self.create_subuniverse();
let new_universe = self.create_superuniverse();
let (result, map) = self.tcx.replace_late_bound_regions(binder, |br| {
self.tcx.mk_region(ty::RePlaceholder(ty::Placeholder {

View file

@ -1494,12 +1494,12 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
}
/// Create and return a new subunivese of the current universe;
/// update `self.universe` to that new subuniverse. At present,
/// update `self.universe` to that new universe. At present,
/// used only in the NLL subtyping code, which uses the new
/// universe-based scheme instead of the more limited leak-check
/// scheme.
pub fn create_subuniverse(&self) -> ty::UniverseIndex {
let u = self.universe.get().subuniverse();
pub fn create_superuniverse(&self) -> ty::UniverseIndex {
let u = self.universe.get().superuniverse();
self.universe.set(u);
u
}

View file

@ -1457,7 +1457,7 @@ impl<'tcx> InstantiatedPredicates<'tcx> {
/// presence of `for<..>` binders to control what sets of names are
/// visible. Universes are arranged into a tree: the root universe
/// contains names that are always visible. But when you enter into
/// some subuniverse, then it may add names that are only visible
/// some superuniverse, then it may add names that are only visible
/// within that subtree (but it can still name the names of its
/// ancestor universes).
///
@ -1471,10 +1471,10 @@ impl<'tcx> InstantiatedPredicates<'tcx> {
/// ```
///
/// The struct name `Foo` is in the root universe U0. But the type
/// parameter `T`, introduced on `bar`, is in a subuniverse U1 --
/// parameter `T`, introduced on `bar`, is in a superuniverse U1 --
/// i.e., within `bar`, we can name both `T` and `Foo`, but outside of
/// `bar`, we cannot name `T`. Then, within the type of `y`, the
/// region `'a` is in a subuniverse U2 of U1, because we can name it
/// region `'a` is in a superuniverse U2 of U1, because we can name it
/// inside the fn type but not outside.
///
/// Universes are used to do type- and trait-checking around these
@ -1489,27 +1489,29 @@ impl<'tcx> InstantiatedPredicates<'tcx> {
/// type -- an idealized representative of "types in general" that we
/// use for checking generic functions.
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
pub struct UniverseIndex(u32);
pub struct UniverseIndex { private: u32 }
impl_stable_hash_for!(struct UniverseIndex { private });
impl UniverseIndex {
/// The root universe, where things that the user defined are
/// visible.
pub const ROOT: Self = UniverseIndex(0);
pub const ROOT: Self = UniverseIndex { private: 0 };
/// The "max universe" -- this isn't really a valid universe, but
/// it's useful sometimes as a "starting value" when you are
/// taking the minimum of a (non-empty!) set of universes.
pub const MAX: Self = UniverseIndex(::std::u32::MAX);
pub const MAX: Self = UniverseIndex { private: ::std::u32::MAX };
/// Creates a universe index from the given integer. Not to be
/// used lightly lest you pick a bad value. But sometimes we
/// convert universe indices into integers and back for various
/// reasons.
pub fn from_u32(index: u32) -> Self {
UniverseIndex(index)
UniverseIndex { private: index }
}
/// A "subuniverse" corresponds to being inside a `forall` quantifier.
/// A "superuniverse" corresponds to being inside a `forall` quantifier.
/// So, for example, suppose we have this type in universe `U`:
///
/// ```
@ -1517,24 +1519,24 @@ impl UniverseIndex {
/// ```
///
/// Once we "enter" into this `for<'a>` quantifier, we are in a
/// subuniverse of `U` -- in this new universe, we can name the
/// superuniverse of `U` -- in this new universe, we can name the
/// region `'a`, but that region was not nameable from `U` because
/// it was not in scope there.
pub fn subuniverse(self) -> UniverseIndex {
UniverseIndex(self.0.checked_add(1).unwrap())
pub fn superuniverse(self) -> UniverseIndex {
UniverseIndex::from_u32(self.private.checked_add(1).unwrap())
}
/// True if the names in this universe are a subset of the names in `other`.
pub fn is_subset_of(self, other: UniverseIndex) -> bool {
self.0 <= other.0
self.private <= other.private
}
pub fn as_u32(&self) -> u32 {
self.0
self.private
}
pub fn as_usize(&self) -> usize {
self.0 as usize
self.private as usize
}
}
@ -1546,7 +1548,7 @@ impl fmt::Debug for UniverseIndex {
impl From<u32> for UniverseIndex {
fn from(index: u32) -> Self {
UniverseIndex(index)
UniverseIndex::from_u32(index)
}
}

View file

@ -57,6 +57,7 @@ CloneTypeFoldableAndLiftImpls! {
::ty::ClosureKind,
::ty::IntVarValue,
::ty::ParamTy,
::ty::UniverseIndex,
::ty::Variance,
::syntax_pos::Span,
}

View file

@ -112,7 +112,7 @@ struct RegionDefinition<'tcx> {
/// Which universe is this region variable defined in? This is
/// most often `ty::UniverseIndex::ROOT`, but when we encounter
/// forall-quantifiers like `for<'a> { 'a = 'b }`, we would create
/// the variable for `'a` in a subuniverse.
/// the variable for `'a` in a superuniverse.
universe: ty::UniverseIndex,
/// If this is 'static or an early-bound region, then this is

View file

@ -148,7 +148,7 @@ crate enum RegionElement {
/// a lifetime parameter).
RootUniversalRegion(RegionVid),
/// A subuniverse from a subuniverse (e.g., instantiated from a
/// A superuniverse from a superuniverse (e.g., instantiated from a
/// `for<'a> fn(&'a u32)` type).
PlaceholderRegion(ty::Placeholder),
}

View file

@ -159,7 +159,7 @@ trait TypeRelatingDelegate<'tcx> {
fn push_outlives(&mut self, sup: ty::Region<'tcx>, sub: ty::Region<'tcx>);
/// Creates a new universe index. Used when instantiating placeholders.
fn next_subuniverse(&mut self) -> ty::UniverseIndex;
fn next_superuniverse(&mut self) -> ty::UniverseIndex;
/// Creates a new region variable representing a higher-ranked
/// region that is instantiated existentially. This creates an
@ -218,8 +218,8 @@ impl NllTypeRelatingDelegate<'me, 'bccx, 'gcx, 'tcx> {
}
impl TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, '_, 'tcx> {
fn next_subuniverse(&mut self) -> ty::UniverseIndex {
self.infcx.create_subuniverse()
fn next_superuniverse(&mut self) -> ty::UniverseIndex {
self.infcx.create_superuniverse()
}
fn next_existential_region_var(&mut self) -> ty::Region<'tcx> {
@ -324,7 +324,7 @@ where
// new universe for the placeholders we will make
// from here out.
let universe = lazy_universe.unwrap_or_else(|| {
let universe = delegate.next_subuniverse();
let universe = delegate.next_superuniverse();
lazy_universe = Some(universe);
universe
});