]> git.lizzy.rs Git - rust.git/blobdiff - compiler/rustc_hir/src/hir.rs
Rollup merge of #101690 - kadiwa4:avoid_iterator_last, r=oli-obk
[rust.git] / compiler / rustc_hir / src / hir.rs
index a668c0e95ce4b1f328a625a3d6762749909093ba..1d62caef9b7a312cca3e7962680da0ece84bb87a 100644 (file)
@@ -259,7 +259,7 @@ pub fn to_ty(&self) -> Ty<'_> {
 
 #[derive(Debug, HashStable_Generic)]
 pub enum GenericArg<'hir> {
-    Lifetime(Lifetime),
+    Lifetime(&'hir Lifetime),
     Type(&'hir Ty<'hir>),
     Const(ConstArg),
     Infer(InferArg),
@@ -300,9 +300,9 @@ pub fn descr(&self) -> &'static str {
     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
+            }
         }
     }
 
@@ -430,7 +430,7 @@ pub enum GenericBound<'hir> {
     Trait(PolyTraitRef<'hir>, TraitBoundModifier),
     // FIXME(davidtwco): Introduce `PolyTraitRef::LangItem`
     LangItemTrait(LangItem, Span, HirId, &'hir GenericArgs<'hir>),
-    Outlives(Lifetime),
+    Outlives(&'hir Lifetime),
 }
 
 impl GenericBound<'_> {
@@ -576,8 +576,7 @@ pub fn tail_span_for_predicate_suggestion(&self) -> Span {
         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)
@@ -756,7 +755,7 @@ pub fn is_param_bound(&self, param_def_id: DefId) -> bool {
 pub struct WhereRegionPredicate<'hir> {
     pub span: Span,
     pub in_where_clause: bool,
-    pub lifetime: Lifetime,
+    pub lifetime: &'hir Lifetime,
     pub bounds: GenericBounds<'hir>,
 }
 
@@ -835,7 +834,16 @@ pub fn node(&self) -> OwnerNode<'tcx> {
 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)
@@ -1059,6 +1067,35 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
     }
 }
 
+// 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., `_`).
@@ -1075,9 +1112,9 @@ pub enum PatKind<'hir> {
     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`.
@@ -1089,7 +1126,7 @@ pub enum PatKind<'hir> {
     /// 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>),
@@ -2372,6 +2409,14 @@ pub fn as_generic_param(&self) -> Option<(DefId, Ident)> {
             _ => 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`.
@@ -2476,6 +2521,7 @@ pub struct OpaqueTy<'hir> {
     pub generics: &'hir Generics<'hir>,
     pub bounds: GenericBounds<'hir>,
     pub origin: OpaqueTyOrigin,
+    pub in_trait: bool,
 }
 
 /// From whence the opaque type came.
@@ -2499,7 +2545,7 @@ pub enum TyKind<'hir> {
     /// 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 (`!`).
@@ -2515,10 +2561,12 @@ pub enum TyKind<'hir> {
     ///
     /// 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
@@ -3474,7 +3522,7 @@ mod size_asserts {
     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);
@@ -3486,17 +3534,17 @@ mod size_asserts {
     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);
 }