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
::{ImplSubject, TyCtxt}
;
11 use rustc_data_structures
::fingerprint
::Fingerprint
;
12 use rustc_data_structures
::stable_hasher
::{HashStable, StableHasher}
;
13 use rustc_hir
::def_id
::{DefId, LocalDefId}
;
15 use rustc_query_system
::ich
::StableHashingContext
;
16 use rustc_span
::DUMMY_SP
;
18 /// Top-level HIR node for current owner. This only contains the node for which
19 /// `HirId::local_id == 0`, and excludes bodies.
21 /// This struct exists to encapsulate all access to the hir_owner query in this module, and to
22 /// implement HashStable without hashing bodies.
23 #[derive(Copy, Clone, Debug)]
24 pub struct Owner
<'tcx
> {
25 node
: OwnerNode
<'tcx
>,
26 hash_without_bodies
: Fingerprint
,
29 impl<'a
, 'tcx
> HashStable
<StableHashingContext
<'a
>> for Owner
<'tcx
> {
31 fn hash_stable(&self, hcx
: &mut StableHashingContext
<'a
>, hasher
: &mut StableHasher
) {
32 let Owner { node: _, hash_without_bodies }
= self;
33 hash_without_bodies
.hash_stable(hcx
, hasher
)
37 /// Gather the LocalDefId for each item-like within a module, including items contained within
38 /// bodies. The Ids are in visitor order. This is used to partition a pass between modules.
39 #[derive(Debug, HashStable)]
40 pub struct ModuleItems
{
41 submodules
: Box
<[LocalDefId
]>,
43 trait_items
: Box
<[TraitItemId
]>,
44 impl_items
: Box
<[ImplItemId
]>,
45 foreign_items
: Box
<[ForeignItemId
]>,
48 impl<'tcx
> TyCtxt
<'tcx
> {
50 pub fn hir(self) -> map
::Map
<'tcx
> {
51 map
::Map { tcx: self }
54 pub fn parent_module(self, id
: HirId
) -> LocalDefId
{
55 self.parent_module_from_def_id(id
.owner
)
58 pub fn impl_subject(self, def_id
: DefId
) -> ImplSubject
<'tcx
> {
59 self.impl_trait_ref(def_id
)
60 .map(ImplSubject
::Trait
)
61 .unwrap_or_else(|| ImplSubject
::Inherent(self.type_of(def_id
)))
65 pub fn provide(providers
: &mut Providers
) {
66 providers
.parent_module_from_def_id
= |tcx
, id
| {
68 hir
.get_module_parent_node(hir
.local_def_id_to_hir_id(id
))
70 providers
.hir_crate
= |tcx
, ()| tcx
.untracked_crate
;
71 providers
.crate_hash
= map
::crate_hash
;
72 providers
.hir_module_items
= map
::hir_module_items
;
73 providers
.hir_owner
= |tcx
, id
| {
74 let owner
= tcx
.hir_crate(()).owners
.get(id
)?
.as_owner()?
;
75 let node
= owner
.node();
76 Some(Owner { node, hash_without_bodies: owner.nodes.hash_without_bodies }
)
78 providers
.local_def_id_to_hir_id
= |tcx
, id
| {
79 let owner
= tcx
.hir_crate(()).owners
[id
].map(|_
| ());
81 MaybeOwner
::Owner(_
) => HirId
::make_owner(id
),
82 MaybeOwner
::Phantom
=> bug
!("No HirId for {:?}", id
),
83 MaybeOwner
::NonOwner(hir_id
) => hir_id
,
86 providers
.hir_owner_nodes
= |tcx
, id
| tcx
.hir_crate(()).owners
[id
].map(|i
| &i
.nodes
);
87 providers
.hir_owner_parent
= |tcx
, id
| {
88 // Accessing the def_key is ok since its value is hashed as part of `id`'s DefPathHash.
89 let parent
= tcx
.untracked_resolutions
.definitions
.def_key(id
).parent
;
90 let parent
= parent
.map_or(CRATE_HIR_ID
, |local_def_index
| {
91 let def_id
= LocalDefId { local_def_index }
;
92 let mut parent_hir_id
= tcx
.hir().local_def_id_to_hir_id(def_id
);
93 if let Some(local_id
) =
94 tcx
.hir_crate(()).owners
[parent_hir_id
.owner
].unwrap().parenting
.get(&id
)
96 parent_hir_id
.local_id
= *local_id
;
102 providers
.hir_attrs
=
103 |tcx
, id
| tcx
.hir_crate(()).owners
[id
].as_owner().map_or(AttributeMap
::EMPTY
, |o
| &o
.attrs
);
104 providers
.source_span
= |tcx
, def_id
| tcx
.resolutions(()).definitions
.def_span(def_id
);
105 providers
.def_span
= |tcx
, def_id
| tcx
.hir().span_if_local(def_id
).unwrap_or(DUMMY_SP
);
106 providers
.fn_arg_names
= |tcx
, id
| {
108 let hir_id
= hir
.local_def_id_to_hir_id(id
.expect_local());
109 if let Some(body_id
) = hir
.maybe_body_owned_by(hir_id
) {
110 tcx
.arena
.alloc_from_iter(hir
.body_param_names(body_id
))
111 } else if let Node
::TraitItem(&TraitItem
{
112 kind
: TraitItemKind
::Fn(_
, TraitFn
::Required(idents
)),
116 tcx
.arena
.alloc_slice(idents
)
118 span_bug
!(hir
.span(hir_id
), "fn_arg_names: unexpected item {:?}", id
);
121 providers
.opt_def_kind
= |tcx
, def_id
| tcx
.hir().opt_def_kind(def_id
.expect_local());
122 providers
.all_local_trait_impls
= |tcx
, ()| &tcx
.resolutions(()).trait_impls
;
123 providers
.expn_that_defined
= |tcx
, id
| {
124 let id
= id
.expect_local();
125 tcx
.resolutions(()).definitions
.expansion_that_defined(id
)
127 providers
.in_scope_traits_map
=
128 |tcx
, id
| tcx
.hir_crate(()).owners
[id
].as_owner().map(|owner_info
| &owner_info
.trait_map
);