#[derive(Debug, HashStable_Generic)]
pub enum GenericArg<'hir> {
- Lifetime(Lifetime),
+ Lifetime(&'hir Lifetime),
Type(&'hir Ty<'hir>),
Const(ConstArg),
Infer(InferArg),
pub fn to_ord(&self) -> ast::ParamKindOrd {
match self {
GenericArg::Lifetime(_) => ast::ParamKindOrd::Lifetime,
- GenericArg::Type(_) => ast::ParamKindOrd::Type,
- GenericArg::Const(_) => ast::ParamKindOrd::Const,
- GenericArg::Infer(_) => ast::ParamKindOrd::Infer,
+ GenericArg::Type(_) | GenericArg::Const(_) | GenericArg::Infer(_) => {
+ ast::ParamKindOrd::TypeOrConst
+ }
}
}
Trait(PolyTraitRef<'hir>, TraitBoundModifier),
// FIXME(davidtwco): Introduce `PolyTraitRef::LangItem`
LangItemTrait(LangItem, Span, HirId, &'hir GenericArgs<'hir>),
- Outlives(Lifetime),
+ Outlives(&'hir Lifetime),
}
impl GenericBound<'_> {
if self.has_where_clause_predicates {
self.predicates
.iter()
- .filter(|p| p.in_where_clause())
- .last()
+ .rfind(|&p| p.in_where_clause())
.map_or(end, |p| p.span())
.shrink_to_hi()
.to(end)
pub struct WhereRegionPredicate<'hir> {
pub span: Span,
pub in_where_clause: bool,
- pub lifetime: Lifetime,
+ pub lifetime: &'hir Lifetime,
pub bounds: GenericBounds<'hir>,
}
impl fmt::Debug for OwnerNodes<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("OwnerNodes")
+ // Do not print all the pointers to all the nodes, as it would be unreadable.
.field("node", &self.nodes[ItemLocalId::from_u32(0)])
+ .field(
+ "parents",
+ &self
+ .nodes
+ .iter_enumerated()
+ .map(|(id, parented_node)| (id, parented_node.as_ref().map(|node| node.parent)))
+ .collect::<Vec<_>>(),
+ )
.field("bodies", &self.bodies)
.field("local_id_to_def_id", &self.local_id_to_def_id)
.field("hash_without_bodies", &self.hash_without_bodies)
}
}
+// Equivalent to `Option<usize>`. That type takes up 16 bytes on 64-bit, but
+// this type only takes up 4 bytes, at the cost of being restricted to a
+// maximum value of `u32::MAX - 1`. In practice, this is more than enough.
+#[derive(Clone, Copy, PartialEq, Eq, Hash, HashStable_Generic)]
+pub struct DotDotPos(u32);
+
+impl DotDotPos {
+ // Panics if n >= u32::MAX.
+ pub fn new(n: Option<usize>) -> Self {
+ match n {
+ Some(n) => {
+ assert!(n < u32::MAX as usize);
+ Self(n as u32)
+ }
+ None => Self(u32::MAX),
+ }
+ }
+
+ pub fn as_opt_usize(&self) -> Option<usize> {
+ if self.0 == u32::MAX { None } else { Some(self.0 as usize) }
+ }
+}
+
+impl fmt::Debug for DotDotPos {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ self.as_opt_usize().fmt(f)
+ }
+}
+
#[derive(Debug, HashStable_Generic)]
pub enum PatKind<'hir> {
/// Represents a wildcard pattern (i.e., `_`).
Struct(QPath<'hir>, &'hir [PatField<'hir>], bool),
/// A tuple struct/variant pattern `Variant(x, y, .., z)`.
- /// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
+ /// If the `..` pattern fragment is present, then `DotDotPos` denotes its position.
/// `0 <= position <= subpats.len()`
- TupleStruct(QPath<'hir>, &'hir [Pat<'hir>], Option<usize>),
+ TupleStruct(QPath<'hir>, &'hir [Pat<'hir>], DotDotPos),
/// An or-pattern `A | B | C`.
/// Invariant: `pats.len() >= 2`.
/// A tuple pattern (e.g., `(a, b)`).
/// If the `..` pattern fragment is present, then `Option<usize>` denotes its position.
/// `0 <= position <= subpats.len()`
- Tuple(&'hir [Pat<'hir>], Option<usize>),
+ Tuple(&'hir [Pat<'hir>], DotDotPos),
/// A `box` pattern.
Box(&'hir Pat<'hir>),
_ => None,
}
}
+
+ pub fn peel_refs(&self) -> &Self {
+ let mut final_ty = self;
+ while let TyKind::Rptr(_, MutTy { ty, .. }) = &final_ty.kind {
+ final_ty = &ty;
+ }
+ final_ty
+ }
}
/// Not represented directly in the AST; referred to by name through a `ty_path`.
pub generics: &'hir Generics<'hir>,
pub bounds: GenericBounds<'hir>,
pub origin: OpaqueTyOrigin,
+ pub in_trait: bool,
}
/// From whence the opaque type came.
/// A raw pointer (i.e., `*const T` or `*mut T`).
Ptr(MutTy<'hir>),
/// A reference (i.e., `&'a T` or `&'a mut T`).
- Rptr(Lifetime, MutTy<'hir>),
+ Rptr(&'hir Lifetime, MutTy<'hir>),
/// A bare function (e.g., `fn(usize) -> bool`).
BareFn(&'hir BareFnTy<'hir>),
/// The never type (`!`).
///
/// The generic argument list contains the lifetimes (and in the future
/// possibly parameters) that are actually bound on the `impl Trait`.
- OpaqueDef(ItemId, &'hir [GenericArg<'hir>]),
+ ///
+ /// The last parameter specifies whether this opaque appears in a trait definition.
+ OpaqueDef(ItemId, &'hir [GenericArg<'hir>], bool),
/// A trait object type `Bound1 + Bound2 + Bound3`
/// where `Bound` is a trait or a lifetime.
- TraitObject(&'hir [PolyTraitRef<'hir>], Lifetime, TraitObjectSyntax),
+ TraitObject(&'hir [PolyTraitRef<'hir>], &'hir Lifetime, TraitObjectSyntax),
/// Unused for now.
Typeof(AnonConst),
/// `TyKind::Infer` means the type should be inferred instead of it having been
static_assert_size!(ForeignItem<'_>, 72);
static_assert_size!(ForeignItemKind<'_>, 40);
#[cfg(not(bootstrap))]
- static_assert_size!(GenericArg<'_>, 32);
+ static_assert_size!(GenericArg<'_>, 24);
static_assert_size!(GenericBound<'_>, 48);
static_assert_size!(Generics<'_>, 56);
static_assert_size!(Impl<'_>, 80);
static_assert_size!(ItemKind<'_>, 48);
static_assert_size!(Local<'_>, 64);
static_assert_size!(Param<'_>, 32);
- static_assert_size!(Pat<'_>, 88);
- static_assert_size!(PatKind<'_>, 64);
+ static_assert_size!(Pat<'_>, 72);
+ static_assert_size!(PatKind<'_>, 48);
static_assert_size!(Path<'_>, 48);
static_assert_size!(PathSegment<'_>, 56);
static_assert_size!(QPath<'_>, 24);
static_assert_size!(Stmt<'_>, 32);
static_assert_size!(StmtKind<'_>, 16);
#[cfg(not(bootstrap))]
- static_assert_size!(TraitItem<'static>, 88);
+ static_assert_size!(TraitItem<'_>, 88);
#[cfg(not(bootstrap))]
static_assert_size!(TraitItemKind<'_>, 48);
- static_assert_size!(Ty<'_>, 72);
- static_assert_size!(TyKind<'_>, 56);
+ static_assert_size!(Ty<'_>, 48);
+ static_assert_size!(TyKind<'_>, 32);
}