/// at least as big as the scope `fr.scope`".
pub struct FreeRegion {
pub scope: DefId,
- pub bound_region: BoundRegion,
+ pub bound_region: BoundRegionKind,
}
#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, TyEncodable, TyDecodable, Copy)]
#[derive(HashStable)]
-pub enum BoundRegion {
+pub enum BoundRegionKind {
/// An anonymous region parameter for a given fn (&T)
BrAnon(u32),
BrEnv,
}
-impl BoundRegion {
- pub fn is_named(&self) -> bool {
- match *self {
- BoundRegion::BrNamed(_, name) => name != kw::UnderscoreLifetime,
- _ => false,
- }
- }
+#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, Debug, PartialOrd, Ord)]
+#[derive(HashStable)]
+pub struct BoundRegion {
+ pub kind: BoundRegionKind,
+}
+impl BoundRegion {
/// When canonicalizing, we replace unbound inference variables and free
/// regions with anonymous late bound regions. This method asserts that
/// we have an anonymous late bound region, which hence may refer to
/// a canonical variable.
pub fn assert_bound_var(&self) -> BoundVar {
- match *self {
- BoundRegion::BrAnon(var) => BoundVar::from_u32(var),
+ match self.kind {
+ BoundRegionKind::BrAnon(var) => BoundVar::from_u32(var),
_ => bug!("bound region is not anonymous"),
}
}
}
+impl BoundRegionKind {
+ pub fn is_named(&self) -> bool {
+ match *self {
+ BoundRegionKind::BrNamed(_, name) => name != kw::UnderscoreLifetime,
+ _ => false,
+ }
+ }
+}
+
+/// Defines the kinds of types.
+///
/// N.B., if you change this, you'll probably want to change the corresponding
/// AST structure in `librustc_ast/ast.rs` as well.
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable, Debug)]
/// A primitive floating-point type. For example, `f64`.
Float(ast::FloatTy),
- /// Structures, enumerations and unions.
+ /// Algebraic data types (ADT). For example: structures, enumerations and unions.
///
/// InternalSubsts here, possibly against intuition, *may* contain `Param`s.
/// That is, even after substitution it is possible that there are type
FnPtr(PolyFnSig<'tcx>),
/// A trait, defined with `trait`.
- Dynamic(Binder<&'tcx List<ExistentialPredicate<'tcx>>>, ty::Region<'tcx>),
+ Dynamic(&'tcx List<Binder<ExistentialPredicate<'tcx>>>, ty::Region<'tcx>),
/// The anonymous type of a closure. Used to represent the type of
/// `|a| a`.
/// `|a| yield a`.
Generator(DefId, SubstsRef<'tcx>, hir::Movability),
- /// A type representin the types stored inside a generator.
+ /// A type representing the types stored inside a generator.
/// This should only appear in GeneratorInteriors.
GeneratorWitness(Binder<&'tcx List<Ty<'tcx>>>),
- /// The never type `!`
+ /// The never type `!`.
Never,
/// A tuple type. For example, `(i32, bool)`.
}
}
-impl<'tcx> List<ExistentialPredicate<'tcx>> {
+impl<'tcx> List<ty::Binder<ExistentialPredicate<'tcx>>> {
/// Returns the "principal `DefId`" of this set of existential predicates.
///
/// A Rust trait object type consists (in addition to a lifetime bound)
/// is `{Send, Sync}`, while there is no principal. These trait objects
/// have a "trivial" vtable consisting of just the size, alignment,
/// and destructor.
- pub fn principal(&self) -> Option<ExistentialTraitRef<'tcx>> {
- match self[0] {
- ExistentialPredicate::Trait(tr) => Some(tr),
- _ => None,
- }
+ pub fn principal(&self) -> Option<ty::Binder<ExistentialTraitRef<'tcx>>> {
+ self[0]
+ .map_bound(|this| match this {
+ ExistentialPredicate::Trait(tr) => Some(tr),
+ _ => None,
+ })
+ .transpose()
}
pub fn principal_def_id(&self) -> Option<DefId> {
- self.principal().map(|trait_ref| trait_ref.def_id)
+ self.principal().map(|trait_ref| trait_ref.skip_binder().def_id)
}
#[inline]
pub fn projection_bounds<'a>(
&'a self,
- ) -> impl Iterator<Item = ExistentialProjection<'tcx>> + 'a {
- self.iter().filter_map(|predicate| match predicate {
- ExistentialPredicate::Projection(projection) => Some(projection),
- _ => None,
+ ) -> impl Iterator<Item = ty::Binder<ExistentialProjection<'tcx>>> + 'a {
+ self.iter().filter_map(|predicate| {
+ predicate
+ .map_bound(|pred| match pred {
+ ExistentialPredicate::Projection(projection) => Some(projection),
+ _ => None,
+ })
+ .transpose()
})
}
#[inline]
pub fn auto_traits<'a>(&'a self) -> impl Iterator<Item = DefId> + 'a {
- self.iter().filter_map(|predicate| match predicate {
+ self.iter().filter_map(|predicate| match predicate.skip_binder() {
ExistentialPredicate::AutoTrait(did) => Some(did),
_ => None,
})
}
}
-impl<'tcx> Binder<&'tcx List<ExistentialPredicate<'tcx>>> {
- pub fn principal(&self) -> Option<ty::Binder<ExistentialTraitRef<'tcx>>> {
- self.map_bound(|b| b.principal()).transpose()
- }
-
- pub fn principal_def_id(&self) -> Option<DefId> {
- self.skip_binder().principal_def_id()
- }
-
- #[inline]
- pub fn projection_bounds<'a>(
- &'a self,
- ) -> impl Iterator<Item = PolyExistentialProjection<'tcx>> + 'a {
- self.skip_binder().projection_bounds().map(Binder::bind)
- }
-
- #[inline]
- pub fn auto_traits<'a>(&'a self) -> impl Iterator<Item = DefId> + 'a {
- self.skip_binder().auto_traits()
- }
-
- pub fn iter<'a>(
- &'a self,
- ) -> impl DoubleEndedIterator<Item = Binder<ExistentialPredicate<'tcx>>> + 'tcx {
- self.skip_binder().iter().map(Binder::bind)
- }
-}
-
/// A complete reference to a trait. These take numerous guises in syntax,
/// but perhaps the most recognizable form is in a where-clause:
///
pub fn has_name(&self) -> bool {
match *self {
RegionKind::ReEarlyBound(ebr) => ebr.has_name(),
- RegionKind::ReLateBound(_, br) => br.is_named(),
+ RegionKind::ReLateBound(_, br) => br.kind.is_named(),
RegionKind::ReFree(fr) => fr.bound_region.is_named(),
RegionKind::ReStatic => true,
RegionKind::ReVar(..) => false,