1 //! HIR datatypes. See the [rustc dev guide] for more info.
3 //! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/hir.html
9 use crate::ty
::query
::Providers
;
10 use crate::ty
::{DefIdTree, ImplSubject, TyCtxt}
;
11 use rustc_data_structures
::fingerprint
::Fingerprint
;
12 use rustc_data_structures
::stable_hasher
::{HashStable, StableHasher}
;
13 use rustc_data_structures
::sync
::{par_for_each_in, Send, Sync}
;
14 use rustc_hir
::def_id
::{DefId, LocalDefId}
;
16 use rustc_query_system
::ich
::StableHashingContext
;
17 use rustc_span
::{ExpnId, DUMMY_SP}
;
19 /// Top-level HIR node for current owner. This only contains the node for which
20 /// `HirId::local_id == 0`, and excludes bodies.
22 /// This struct exists to encapsulate all access to the hir_owner query in this module, and to
23 /// implement HashStable without hashing bodies.
24 #[derive(Copy, Clone, Debug)]
25 pub struct Owner
<'tcx
> {
26 node
: OwnerNode
<'tcx
>,
27 hash_without_bodies
: Fingerprint
,
30 impl<'a
, 'tcx
> HashStable
<StableHashingContext
<'a
>> for Owner
<'tcx
> {
32 fn hash_stable(&self, hcx
: &mut StableHashingContext
<'a
>, hasher
: &mut StableHasher
) {
33 let Owner { node: _, hash_without_bodies }
= self;
34 hash_without_bodies
.hash_stable(hcx
, hasher
)
38 /// Gather the LocalDefId for each item-like within a module, including items contained within
39 /// bodies. The Ids are in visitor order. This is used to partition a pass between modules.
40 #[derive(Debug, HashStable, Encodable, Decodable)]
41 pub struct ModuleItems
{
42 submodules
: Box
<[LocalDefId
]>,
44 trait_items
: Box
<[TraitItemId
]>,
45 impl_items
: Box
<[ImplItemId
]>,
46 foreign_items
: Box
<[ForeignItemId
]>,
47 body_owners
: Box
<[LocalDefId
]>,
51 pub fn items(&self) -> impl Iterator
<Item
= ItemId
> + '_
{
52 self.items
.iter().copied()
55 pub fn trait_items(&self) -> impl Iterator
<Item
= TraitItemId
> + '_
{
56 self.trait_items
.iter().copied()
59 pub fn impl_items(&self) -> impl Iterator
<Item
= ImplItemId
> + '_
{
60 self.impl_items
.iter().copied()
63 pub fn foreign_items(&self) -> impl Iterator
<Item
= ForeignItemId
> + '_
{
64 self.foreign_items
.iter().copied()
67 pub fn definitions(&self) -> impl Iterator
<Item
= LocalDefId
> + '_
{
71 .chain(self.trait_items
.iter().map(|id
| id
.def_id
))
72 .chain(self.impl_items
.iter().map(|id
| id
.def_id
))
73 .chain(self.foreign_items
.iter().map(|id
| id
.def_id
))
76 pub fn par_items(&self, f
: impl Fn(ItemId
) + Send
+ Sync
) {
77 par_for_each_in(&self.items
[..], |&id
| f(id
))
80 pub fn par_trait_items(&self, f
: impl Fn(TraitItemId
) + Send
+ Sync
) {
81 par_for_each_in(&self.trait_items
[..], |&id
| f(id
))
84 pub fn par_impl_items(&self, f
: impl Fn(ImplItemId
) + Send
+ Sync
) {
85 par_for_each_in(&self.impl_items
[..], |&id
| f(id
))
88 pub fn par_foreign_items(&self, f
: impl Fn(ForeignItemId
) + Send
+ Sync
) {
89 par_for_each_in(&self.foreign_items
[..], |&id
| f(id
))
93 impl<'tcx
> TyCtxt
<'tcx
> {
95 pub fn hir(self) -> map
::Map
<'tcx
> {
96 map
::Map { tcx: self }
99 pub fn parent_module(self, id
: HirId
) -> LocalDefId
{
100 self.parent_module_from_def_id(id
.owner
)
103 pub fn impl_subject(self, def_id
: DefId
) -> ImplSubject
<'tcx
> {
104 self.impl_trait_ref(def_id
)
105 .map(ImplSubject
::Trait
)
106 .unwrap_or_else(|| ImplSubject
::Inherent(self.type_of(def_id
)))
110 pub fn provide(providers
: &mut Providers
) {
111 providers
.parent_module_from_def_id
= |tcx
, id
| {
113 hir
.get_module_parent_node(hir
.local_def_id_to_hir_id(id
))
115 providers
.hir_crate_items
= map
::hir_crate_items
;
116 providers
.crate_hash
= map
::crate_hash
;
117 providers
.hir_module_items
= map
::hir_module_items
;
118 providers
.hir_owner
= |tcx
, id
| {
119 let owner
= tcx
.hir_crate(()).owners
.get(id
)?
.as_owner()?
;
120 let node
= owner
.node();
121 Some(Owner { node, hash_without_bodies: owner.nodes.hash_without_bodies }
)
123 providers
.local_def_id_to_hir_id
= |tcx
, id
| {
124 let owner
= tcx
.hir_crate(()).owners
[id
].map(|_
| ());
126 MaybeOwner
::Owner(_
) => HirId
::make_owner(id
),
127 MaybeOwner
::Phantom
=> bug
!("No HirId for {:?}", id
),
128 MaybeOwner
::NonOwner(hir_id
) => hir_id
,
131 providers
.hir_owner_nodes
= |tcx
, id
| tcx
.hir_crate(()).owners
[id
].map(|i
| &i
.nodes
);
132 providers
.hir_owner_parent
= |tcx
, id
| {
133 // Accessing the local_parent is ok since its value is hashed as part of `id`'s DefPathHash.
134 tcx
.opt_local_parent(id
).map_or(CRATE_HIR_ID
, |parent
| {
135 let mut parent_hir_id
= tcx
.hir().local_def_id_to_hir_id(parent
);
136 if let Some(local_id
) =
137 tcx
.hir_crate(()).owners
[parent_hir_id
.owner
].unwrap().parenting
.get(&id
)
139 parent_hir_id
.local_id
= *local_id
;
144 providers
.hir_attrs
=
145 |tcx
, id
| tcx
.hir_crate(()).owners
[id
].as_owner().map_or(AttributeMap
::EMPTY
, |o
| &o
.attrs
);
146 providers
.source_span
=
147 |tcx
, def_id
| tcx
.resolutions(()).source_span
.get(def_id
).copied().unwrap_or(DUMMY_SP
);
148 providers
.def_span
= |tcx
, def_id
| {
149 let def_id
= def_id
.expect_local();
150 let hir_id
= tcx
.hir().local_def_id_to_hir_id(def_id
);
151 tcx
.hir().opt_span(hir_id
).unwrap_or(DUMMY_SP
)
153 providers
.def_ident_span
= |tcx
, def_id
| {
154 let def_id
= def_id
.expect_local();
155 let hir_id
= tcx
.hir().local_def_id_to_hir_id(def_id
);
156 tcx
.hir().opt_ident_span(hir_id
)
158 providers
.fn_arg_names
= |tcx
, id
| {
160 let def_id
= id
.expect_local();
161 let hir_id
= hir
.local_def_id_to_hir_id(def_id
);
162 if let Some(body_id
) = hir
.maybe_body_owned_by(def_id
) {
163 tcx
.arena
.alloc_from_iter(hir
.body_param_names(body_id
))
164 } else if let Node
::TraitItem(&TraitItem
{
165 kind
: TraitItemKind
::Fn(_
, TraitFn
::Required(idents
)),
169 tcx
.arena
.alloc_slice(idents
)
171 span_bug
!(hir
.span(hir_id
), "fn_arg_names: unexpected item {:?}", id
);
174 providers
.opt_def_kind
= |tcx
, def_id
| tcx
.hir().opt_def_kind(def_id
.expect_local());
175 providers
.all_local_trait_impls
= |tcx
, ()| &tcx
.resolutions(()).trait_impls
;
176 providers
.expn_that_defined
= |tcx
, id
| {
177 let id
= id
.expect_local();
178 tcx
.resolutions(()).expn_that_defined
.get(&id
).copied().unwrap_or(ExpnId
::root())
180 providers
.in_scope_traits_map
=
181 |tcx
, id
| tcx
.hir_crate(()).owners
[id
].as_owner().map(|owner_info
| &owner_info
.trait_map
);