]>
Commit | Line | Data |
---|---|---|
ba9703b0 XL |
1 | //! HIR datatypes. See the [rustc dev guide] for more info. |
2 | //! | |
3 | //! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/hir.html | |
4 | ||
5 | pub mod exports; | |
6 | pub mod map; | |
3dfed10e | 7 | pub mod place; |
ba9703b0 XL |
8 | |
9 | use crate::ich::StableHashingContext; | |
10 | use crate::ty::query::Providers; | |
11 | use crate::ty::TyCtxt; | |
6a06907d | 12 | use rustc_ast::Attribute; |
ba9703b0 XL |
13 | use rustc_data_structures::fingerprint::Fingerprint; |
14 | use rustc_data_structures::fx::FxHashMap; | |
15 | use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; | |
16 | use rustc_hir::def_id::{LocalDefId, LOCAL_CRATE}; | |
f035d41b | 17 | use rustc_hir::*; |
ba9703b0 | 18 | use rustc_index::vec::IndexVec; |
5869c6ff | 19 | use rustc_span::DUMMY_SP; |
6a06907d | 20 | use std::collections::BTreeMap; |
ba9703b0 | 21 | |
5869c6ff | 22 | #[derive(Debug)] |
ba9703b0 XL |
23 | pub struct Owner<'tcx> { |
24 | parent: HirId, | |
25 | node: Node<'tcx>, | |
26 | } | |
27 | ||
28 | impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for Owner<'tcx> { | |
29 | fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { | |
30 | let Owner { parent, node } = self; | |
31 | hcx.while_hashing_hir_bodies(false, |hcx| { | |
32 | parent.hash_stable(hcx, hasher); | |
33 | node.hash_stable(hcx, hasher); | |
34 | }); | |
35 | } | |
36 | } | |
37 | ||
5869c6ff | 38 | #[derive(Clone, Debug)] |
ba9703b0 XL |
39 | pub struct ParentedNode<'tcx> { |
40 | parent: ItemLocalId, | |
41 | node: Node<'tcx>, | |
42 | } | |
43 | ||
5869c6ff | 44 | #[derive(Debug)] |
ba9703b0 XL |
45 | pub struct OwnerNodes<'tcx> { |
46 | hash: Fingerprint, | |
47 | nodes: IndexVec<ItemLocalId, Option<ParentedNode<'tcx>>>, | |
48 | bodies: FxHashMap<ItemLocalId, &'tcx Body<'tcx>>, | |
49 | } | |
50 | ||
51 | impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for OwnerNodes<'tcx> { | |
52 | fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { | |
53 | // We ignore the `nodes` and `bodies` fields since these refer to information included in | |
54 | // `hash` which is hashed in the collector and used for the crate hash. | |
55 | let OwnerNodes { hash, nodes: _, bodies: _ } = *self; | |
56 | hash.hash_stable(hcx, hasher); | |
57 | } | |
58 | } | |
59 | ||
6a06907d XL |
60 | #[derive(Copy, Clone)] |
61 | pub struct AttributeMap<'tcx> { | |
62 | map: &'tcx BTreeMap<HirId, &'tcx [Attribute]>, | |
63 | prefix: LocalDefId, | |
64 | } | |
65 | ||
66 | impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for AttributeMap<'tcx> { | |
67 | fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { | |
68 | let range = self.range(); | |
69 | ||
70 | range.clone().count().hash_stable(hcx, hasher); | |
71 | for (key, value) in range { | |
72 | key.hash_stable(hcx, hasher); | |
73 | value.hash_stable(hcx, hasher); | |
74 | } | |
75 | } | |
76 | } | |
77 | ||
78 | impl<'tcx> std::fmt::Debug for AttributeMap<'tcx> { | |
79 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | |
80 | f.debug_struct("AttributeMap") | |
81 | .field("prefix", &self.prefix) | |
82 | .field("range", &&self.range().collect::<Vec<_>>()[..]) | |
83 | .finish() | |
84 | } | |
85 | } | |
86 | ||
87 | impl<'tcx> AttributeMap<'tcx> { | |
88 | fn get(&self, id: ItemLocalId) -> &'tcx [Attribute] { | |
89 | self.map.get(&HirId { owner: self.prefix, local_id: id }).copied().unwrap_or(&[]) | |
90 | } | |
91 | ||
92 | fn range(&self) -> std::collections::btree_map::Range<'_, rustc_hir::HirId, &[Attribute]> { | |
93 | let local_zero = ItemLocalId::from_u32(0); | |
94 | let range = HirId { owner: self.prefix, local_id: local_zero }..HirId { | |
95 | owner: LocalDefId { local_def_index: self.prefix.local_def_index + 1 }, | |
96 | local_id: local_zero, | |
97 | }; | |
98 | self.map.range(range) | |
99 | } | |
100 | } | |
101 | ||
ba9703b0 XL |
102 | impl<'tcx> TyCtxt<'tcx> { |
103 | #[inline(always)] | |
104 | pub fn hir(self) -> map::Map<'tcx> { | |
105 | map::Map { tcx: self } | |
106 | } | |
107 | ||
108 | pub fn parent_module(self, id: HirId) -> LocalDefId { | |
109 | self.parent_module_from_def_id(id.owner) | |
110 | } | |
111 | } | |
112 | ||
f035d41b | 113 | pub fn provide(providers: &mut Providers) { |
ba9703b0 XL |
114 | providers.parent_module_from_def_id = |tcx, id| { |
115 | let hir = tcx.hir(); | |
3dfed10e | 116 | hir.local_def_id(hir.get_module_parent_node(hir.local_def_id_to_hir_id(id))) |
ba9703b0 XL |
117 | }; |
118 | providers.hir_crate = |tcx, _| tcx.untracked_crate; | |
119 | providers.index_hir = map::index_hir; | |
6a06907d | 120 | providers.hir_module_items = |tcx, id| &tcx.untracked_crate.modules[&id]; |
ba9703b0 | 121 | providers.hir_owner = |tcx, id| tcx.index_hir(LOCAL_CRATE).map[id].signature; |
f9f354fc | 122 | providers.hir_owner_nodes = |tcx, id| tcx.index_hir(LOCAL_CRATE).map[id].with_bodies.as_deref(); |
6a06907d | 123 | providers.hir_attrs = |tcx, id| AttributeMap { map: &tcx.untracked_crate.attrs, prefix: id }; |
5869c6ff | 124 | providers.def_span = |tcx, def_id| tcx.hir().span_if_local(def_id).unwrap_or(DUMMY_SP); |
f035d41b XL |
125 | providers.fn_arg_names = |tcx, id| { |
126 | let hir = tcx.hir(); | |
3dfed10e | 127 | let hir_id = hir.local_def_id_to_hir_id(id.expect_local()); |
f035d41b XL |
128 | if let Some(body_id) = hir.maybe_body_owned_by(hir_id) { |
129 | tcx.arena.alloc_from_iter(hir.body_param_names(body_id)) | |
130 | } else if let Node::TraitItem(&TraitItem { | |
131 | kind: TraitItemKind::Fn(_, TraitFn::Required(idents)), | |
132 | .. | |
133 | }) = hir.get(hir_id) | |
134 | { | |
135 | tcx.arena.alloc_slice(idents) | |
136 | } else { | |
137 | span_bug!(hir.span(hir_id), "fn_arg_names: unexpected item {:?}", id); | |
138 | } | |
139 | }; | |
5869c6ff | 140 | providers.opt_def_kind = |tcx, def_id| tcx.hir().opt_def_kind(def_id.expect_local()); |
ba9703b0 | 141 | } |