2020-03-05 18:07:42 -03:00
|
|
|
//! HIR datatypes. See the [rustc dev guide] for more info.
|
2020-01-02 03:39:11 +01:00
|
|
|
//!
|
2020-03-09 18:33:04 -03:00
|
|
|
//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/hir.html
|
2020-01-02 03:39:11 +01:00
|
|
|
|
2020-01-02 04:53:12 +01:00
|
|
|
pub mod exports;
|
2020-01-02 03:39:11 +01:00
|
|
|
pub mod map;
|
|
|
|
|
2020-02-09 12:13:08 +01:00
|
|
|
use crate::ich::StableHashingContext;
|
2020-01-02 03:39:11 +01:00
|
|
|
use crate::ty::query::Providers;
|
2020-02-06 11:59:29 +01:00
|
|
|
use crate::ty::TyCtxt;
|
2020-02-07 13:13:35 +01:00
|
|
|
use rustc_data_structures::cold_path;
|
2020-02-07 11:14:47 +01:00
|
|
|
use rustc_data_structures::fx::FxHashMap;
|
2020-02-09 12:13:08 +01:00
|
|
|
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
2020-02-11 14:38:16 +01:00
|
|
|
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
|
2020-02-06 11:59:29 +01:00
|
|
|
use rustc_hir::print;
|
2020-02-07 11:14:47 +01:00
|
|
|
use rustc_hir::Body;
|
2020-02-06 12:46:26 +01:00
|
|
|
use rustc_hir::Crate;
|
2020-02-11 14:38:16 +01:00
|
|
|
use rustc_hir::HirId;
|
2020-02-07 11:14:47 +01:00
|
|
|
use rustc_hir::ItemLocalId;
|
|
|
|
use rustc_hir::Node;
|
|
|
|
use rustc_index::vec::IndexVec;
|
2020-02-06 11:59:29 +01:00
|
|
|
use std::ops::Deref;
|
|
|
|
|
2020-02-07 11:14:47 +01:00
|
|
|
#[derive(HashStable)]
|
|
|
|
pub struct HirOwner<'tcx> {
|
|
|
|
parent: HirId,
|
|
|
|
node: Node<'tcx>,
|
|
|
|
}
|
|
|
|
|
2020-02-09 12:13:08 +01:00
|
|
|
#[derive(Clone)]
|
2020-02-07 11:14:47 +01:00
|
|
|
pub struct HirItem<'tcx> {
|
|
|
|
parent: ItemLocalId,
|
|
|
|
node: Node<'tcx>,
|
|
|
|
}
|
|
|
|
|
2020-02-09 12:13:08 +01:00
|
|
|
impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for HirItem<'tcx> {
|
|
|
|
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
|
|
|
|
let HirItem { parent, node } = self;
|
|
|
|
hcx.while_hashing_hir_bodies(false, |hcx| {
|
|
|
|
parent.hash_stable(hcx, hasher);
|
|
|
|
node.hash_stable(hcx, hasher);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-07 11:14:47 +01:00
|
|
|
pub struct HirOwnerItems<'tcx> {
|
2020-02-09 12:13:08 +01:00
|
|
|
owner: Node<'tcx>,
|
2020-02-07 11:14:47 +01:00
|
|
|
items: IndexVec<ItemLocalId, Option<HirItem<'tcx>>>,
|
|
|
|
bodies: FxHashMap<ItemLocalId, &'tcx Body<'tcx>>,
|
|
|
|
}
|
|
|
|
|
2020-02-09 12:13:08 +01:00
|
|
|
impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for HirOwnerItems<'tcx> {
|
|
|
|
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
|
|
|
|
// We ignore the `items` and `bodies` fields since these refer to information reachable
|
|
|
|
// when hashing `owner` with its bodies.
|
|
|
|
let HirOwnerItems { owner, items: _, bodies: _ } = *self;
|
|
|
|
hcx.while_hashing_hir_bodies(true, |hcx| {
|
|
|
|
owner.hash_stable(hcx, hasher);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-06 11:59:29 +01:00
|
|
|
/// A wrapper type which allows you to access HIR.
|
|
|
|
#[derive(Clone)]
|
|
|
|
pub struct Hir<'tcx> {
|
|
|
|
tcx: TyCtxt<'tcx>,
|
|
|
|
map: &'tcx map::Map<'tcx>,
|
|
|
|
}
|
|
|
|
|
2020-02-06 12:46:26 +01:00
|
|
|
impl<'tcx> Hir<'tcx> {
|
|
|
|
pub fn krate(&self) -> &'tcx Crate<'tcx> {
|
|
|
|
self.tcx.hir_crate(LOCAL_CRATE)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-06 11:59:29 +01:00
|
|
|
impl<'tcx> Deref for Hir<'tcx> {
|
|
|
|
type Target = &'tcx map::Map<'tcx>;
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
fn deref(&self) -> &Self::Target {
|
|
|
|
&self.map
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'hir> print::PpAnn for Hir<'hir> {
|
|
|
|
fn nested(&self, state: &mut print::State<'_>, nested: print::Nested) {
|
|
|
|
self.map.nested(state, nested)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'tcx> TyCtxt<'tcx> {
|
|
|
|
#[inline(always)]
|
|
|
|
pub fn hir(self) -> Hir<'tcx> {
|
2020-02-07 13:13:35 +01:00
|
|
|
let map = self.late_hir_map.load();
|
|
|
|
let map = if unlikely!(map.is_none()) {
|
|
|
|
cold_path(|| {
|
|
|
|
let map = self.hir_map(LOCAL_CRATE);
|
|
|
|
self.late_hir_map.store(Some(map));
|
|
|
|
map
|
|
|
|
})
|
|
|
|
} else {
|
|
|
|
map.unwrap()
|
|
|
|
};
|
|
|
|
Hir { tcx: self, map }
|
2020-02-06 11:59:29 +01:00
|
|
|
}
|
2020-02-11 14:38:16 +01:00
|
|
|
|
|
|
|
pub fn parent_module(self, id: HirId) -> DefId {
|
|
|
|
self.parent_module_from_def_id(DefId::local(id.owner))
|
|
|
|
}
|
2020-02-06 11:59:29 +01:00
|
|
|
}
|
2020-01-02 03:39:11 +01:00
|
|
|
|
|
|
|
pub fn provide(providers: &mut Providers<'_>) {
|
2020-02-11 14:38:16 +01:00
|
|
|
providers.parent_module_from_def_id = |tcx, id| {
|
|
|
|
let hir = tcx.hir();
|
2020-02-22 19:53:10 +01:00
|
|
|
hir.local_def_id(hir.get_module_parent_node(hir.as_local_hir_id(id).unwrap()))
|
2020-02-11 14:38:16 +01:00
|
|
|
};
|
2020-02-07 13:13:35 +01:00
|
|
|
providers.hir_crate = |tcx, _| tcx.hir_map(LOCAL_CRATE).untracked_krate();
|
|
|
|
providers.hir_map = |tcx, id| {
|
|
|
|
assert_eq!(id, LOCAL_CRATE);
|
|
|
|
let early = tcx.hir_map.steal();
|
|
|
|
tcx.arena.alloc(map::Map {
|
|
|
|
tcx,
|
|
|
|
krate: early.krate,
|
|
|
|
|
|
|
|
crate_hash: early.crate_hash,
|
|
|
|
|
|
|
|
owner_map: early.owner_map,
|
|
|
|
owner_items_map: early.owner_items_map,
|
|
|
|
|
|
|
|
definitions: early.definitions,
|
|
|
|
|
|
|
|
hir_to_node_id: early.hir_to_node_id,
|
|
|
|
})
|
|
|
|
};
|
2020-02-07 18:25:36 +01:00
|
|
|
providers.hir_module_items = |tcx, id| {
|
|
|
|
assert_eq!(id.krate, LOCAL_CRATE);
|
|
|
|
let hir = tcx.hir();
|
|
|
|
let module = hir.as_local_hir_id(id).unwrap();
|
|
|
|
&hir.untracked_krate().modules[&module]
|
|
|
|
};
|
2020-02-07 13:13:35 +01:00
|
|
|
providers.hir_owner = |tcx, id| {
|
|
|
|
assert_eq!(id.krate, LOCAL_CRATE);
|
|
|
|
*tcx.hir().map.owner_map.get(&id.index).unwrap()
|
|
|
|
};
|
|
|
|
providers.hir_owner_items = |tcx, id| {
|
|
|
|
assert_eq!(id.krate, LOCAL_CRATE);
|
|
|
|
*tcx.hir().map.owner_items_map.get(&id.index).unwrap()
|
|
|
|
};
|
2020-01-02 03:39:11 +01:00
|
|
|
map::provide(providers);
|
|
|
|
}
|