use crate::def::{CtorKind, DefKind, Res};
-use crate::def_id::{DefId, CRATE_DEF_ID};
+use crate::def_id::DefId;
crate use crate::hir_id::{HirId, ItemLocalId};
+use crate::intravisit::FnKind;
use crate::LangItem;
use rustc_ast::util::parser::ExprPrecedence;
pub use rustc_ast::{BorrowKind, ImplPolarity, IsAuto};
pub use rustc_ast::{CaptureBy, Movability, Mutability};
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
+use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::sorted_map::SortedMap;
use rustc_index::vec::IndexVec;
use rustc_macros::HashStable_Generic;
use rustc_span::source_map::Spanned;
use rustc_target::spec::abi::Abi;
use smallvec::SmallVec;
-use std::collections::BTreeMap;
use std::fmt;
#[derive(Copy, Clone, Encodable, HashStable_Generic)]
match *self {
LifetimeName::ImplicitObjectLifetimeDefault
| LifetimeName::Implicit
- | LifetimeName::Error => Ident::invalid(),
+ | LifetimeName::Error => Ident::empty(),
LifetimeName::Underscore => Ident::with_dummy_span(kw::UnderscoreLifetime),
LifetimeName::Static => Ident::with_dummy_span(kw::StaticLifetime),
LifetimeName::Param(param_name) => param_name.ident(),
}
pub fn invalid() -> Self {
- Self::from_ident(Ident::invalid())
+ Self::from_ident(Ident::empty())
}
pub fn args(&self) -> &GenericArgs<'hir> {
}
pub fn is_synthetic(&self) -> bool {
- matches!(self, GenericArg::Lifetime(lifetime) if lifetime.name.ident() == Ident::invalid())
+ matches!(self, GenericArg::Lifetime(lifetime) if lifetime.name.ident() == Ident::empty())
}
pub fn descr(&self) -> &'static str {
},
Type {
default: Option<&'hir Ty<'hir>>,
- synthetic: Option<SyntheticTyParamKind>,
+ synthetic: bool,
},
Const {
ty: &'hir Ty<'hir>,
}
}
-/// Synthetic type parameters are converted to another form during lowering; this allows
-/// us to track the original form they had, and is useful for error messages.
-#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Hash, Debug)]
-#[derive(HashStable_Generic)]
-pub enum SyntheticTyParamKind {
- ImplTrait,
- // Created by the `#[rustc_synthetic]` attribute.
- FromAttr,
-}
-
/// A where-clause in a definition.
#[derive(Debug, HashStable_Generic)]
pub struct WhereClause<'hir> {
pub bounds: GenericBounds<'hir>,
}
+impl WhereBoundPredicate<'hir> {
+ /// Returns `true` if `param_def_id` matches the `bounded_ty` of this predicate.
+ pub fn is_param_bound(&self, param_def_id: DefId) -> bool {
+ let path = match self.bounded_ty.kind {
+ TyKind::Path(QPath::Resolved(None, path)) => path,
+ _ => return false,
+ };
+ match path.res {
+ Res::Def(DefKind::TyParam, def_id) | Res::SelfTy(Some(def_id), None) => {
+ def_id == param_def_id
+ }
+ _ => false,
+ }
+ }
+}
+
/// A lifetime predicate (e.g., `'a: 'b + 'c`).
#[derive(Debug, HashStable_Generic)]
pub struct WhereRegionPredicate<'hir> {
pub rhs_ty: &'hir Ty<'hir>,
}
-/// The top-level data structure that stores the entire contents of
-/// the crate currently being compiled.
+/// HIR node coupled with its parent's id in the same HIR owner.
///
-/// For more details, see the [rustc dev guide].
-///
-/// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/hir.html
-#[derive(Debug)]
-pub struct Crate<'hir> {
- pub owners: IndexVec<LocalDefId, Option<OwnerNode<'hir>>>,
- pub bodies: BTreeMap<BodyId, Body<'hir>>,
-
- /// Map indicating what traits are in scope for places where this
- /// is relevant; generated by resolve.
- pub trait_map: FxHashMap<LocalDefId, FxHashMap<ItemLocalId, Box<[TraitCandidate]>>>,
-
- /// Collected attributes from HIR nodes.
- pub attrs: BTreeMap<HirId, &'hir [Attribute]>,
+/// The parent is trash when the node is a HIR owner.
+#[derive(Clone, Debug)]
+pub struct ParentedNode<'tcx> {
+ pub parent: ItemLocalId,
+ pub node: Node<'tcx>,
}
-impl Crate<'hir> {
- pub fn module(&self) -> &'hir Mod<'hir> {
- if let Some(OwnerNode::Crate(m)) = self.owners[CRATE_DEF_ID] { m } else { panic!() }
- }
+/// Attributes owned by a HIR owner.
+#[derive(Debug)]
+pub struct AttributeMap<'tcx> {
+ pub map: SortedMap<ItemLocalId, &'tcx [Attribute]>,
+ pub hash: Fingerprint,
+}
- pub fn item(&self, id: ItemId) -> &'hir Item<'hir> {
- self.owners[id.def_id].as_ref().unwrap().expect_item()
- }
+impl<'tcx> AttributeMap<'tcx> {
+ pub const EMPTY: &'static AttributeMap<'static> =
+ &AttributeMap { map: SortedMap::new(), hash: Fingerprint::ZERO };
- pub fn trait_item(&self, id: TraitItemId) -> &'hir TraitItem<'hir> {
- self.owners[id.def_id].as_ref().unwrap().expect_trait_item()
+ #[inline]
+ pub fn get(&self, id: ItemLocalId) -> &'tcx [Attribute] {
+ self.map.get(&id).copied().unwrap_or(&[])
}
+}
- pub fn impl_item(&self, id: ImplItemId) -> &'hir ImplItem<'hir> {
- self.owners[id.def_id].as_ref().unwrap().expect_impl_item()
- }
+/// Map of all HIR nodes inside the current owner.
+/// These nodes are mapped by `ItemLocalId` alongside the index of their parent node.
+/// The HIR tree, including bodies, is pre-hashed.
+#[derive(Debug)]
+pub struct OwnerNodes<'tcx> {
+ /// Pre-computed hash of the full HIR.
+ pub hash_including_bodies: Fingerprint,
+ /// Pre-computed hash of the item signature, sithout recursing into the body.
+ pub hash_without_bodies: Fingerprint,
+ /// Full HIR for the current owner.
+ // The zeroth node's parent should never be accessed: the owner's parent is computed by the
+ // hir_owner_parent query. It is set to `ItemLocalId::INVALID` to force an ICE if accidentally
+ // used.
+ pub nodes: IndexVec<ItemLocalId, Option<ParentedNode<'tcx>>>,
+ /// Content of local bodies.
+ pub bodies: SortedMap<ItemLocalId, &'tcx Body<'tcx>>,
+}
+
+/// Full information resulting from lowering an AST node.
+#[derive(Debug, HashStable_Generic)]
+pub struct OwnerInfo<'hir> {
+ /// Contents of the HIR.
+ pub nodes: OwnerNodes<'hir>,
+ /// Map from each nested owner to its parent's local id.
+ pub parenting: FxHashMap<LocalDefId, ItemLocalId>,
+ /// Collected attributes of the HIR nodes.
+ pub attrs: AttributeMap<'hir>,
+ /// Map indicating what traits are in scope for places where this
+ /// is relevant; generated by resolve.
+ pub trait_map: FxHashMap<ItemLocalId, Box<[TraitCandidate]>>,
+}
- pub fn foreign_item(&self, id: ForeignItemId) -> &'hir ForeignItem<'hir> {
- self.owners[id.def_id].as_ref().unwrap().expect_foreign_item()
+impl<'tcx> OwnerInfo<'tcx> {
+ #[inline]
+ pub fn node(&self) -> OwnerNode<'tcx> {
+ use rustc_index::vec::Idx;
+ let node = self.nodes.nodes[ItemLocalId::new(0)].as_ref().unwrap().node;
+ let node = node.as_owner().unwrap(); // Indexing must ensure it is an OwnerNode.
+ node
}
+}
- pub fn body(&self, id: BodyId) -> &Body<'hir> {
- &self.bodies[&id]
- }
+/// The top-level data structure that stores the entire contents of
+/// the crate currently being compiled.
+///
+/// For more details, see the [rustc dev guide].
+///
+/// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/hir.html
+#[derive(Debug)]
+pub struct Crate<'hir> {
+ pub owners: IndexVec<LocalDefId, Option<OwnerInfo<'hir>>>,
+ pub hir_hash: Fingerprint,
}
/// A block of statements `{ .. }`, which may have a label (in this case the
pub enum LocalSource {
/// A `match _ { .. }`.
Normal,
- /// A desugared `for _ in _ { .. }` loop.
- ForLoopDesugar,
/// When lowering async functions, we create locals within the `async move` so that
/// all parameters are dropped after the future is polled.
///
_ => None,
}
}
+
+ pub fn fn_kind(self) -> Option<FnKind<'hir>> {
+ match self {
+ Node::Item(i) => match i.kind {
+ ItemKind::Fn(ref sig, ref generics, _) => {
+ Some(FnKind::ItemFn(i.ident, generics, sig.header, &i.vis))
+ }
+ _ => None,
+ },
+ Node::TraitItem(ti) => match ti.kind {
+ TraitItemKind::Fn(ref sig, TraitFn::Provided(_)) => {
+ Some(FnKind::Method(ti.ident, sig, None))
+ }
+ _ => None,
+ },
+ Node::ImplItem(ii) => match ii.kind {
+ ImplItemKind::Fn(ref sig, _) => Some(FnKind::Method(ii.ident, sig, Some(&ii.vis))),
+ _ => None,
+ },
+ Node::Expr(e) => match e.kind {
+ ExprKind::Closure(..) => Some(FnKind::Closure),
+ _ => None,
+ },
+ _ => None,
+ }
+ }
}
// Some nodes are used a lot. Make sure they don't unintentionally get bigger.