1#![allow(rustc::usage_of_ty_tykind)]
16#![doc(test(attr(allow(unused_variables), deny(warnings), allow(internal_features))))]
17#![feature(sized_hierarchy)]
18#![feature(trait_alias)]
19use std::fmt::Debug;
22use std::hash::Hash;
23use std::ops::Index;
24
25use bridge::*;
26use context::CompilerCtxt;
27use rustc_data_structures::fx::{self, FxIndexMap};
28use rustc_middle::mir;
29use rustc_middle::mir::interpret::AllocId;
30use rustc_middle::ty::{self, Ty, TyCtxt};
31use rustc_span::Span;
32use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE};
33
34pub mod alloc;
35pub mod bridge;
36mod builder;
37pub mod context;
38
39#[deprecated(note = "please use `rustc_public::rustc_internal` instead")]
40pub mod rustc_internal {}
41
42pub trait Cacheable = Copy + Debug + PartialEq + IndexedVal;
44
45pub struct Tables<'tcx, B: Bridge> {
46 pub def_ids: IndexMap<DefId, B::DefId>,
47 pub alloc_ids: IndexMap<AllocId, B::AllocId>,
48 pub spans: IndexMap<rustc_span::Span, B::Span>,
49 pub types: IndexMap<Ty<'tcx>, B::Ty>,
50 pub instances: IndexMap<ty::Instance<'tcx>, B::InstanceDef>,
51 pub ty_consts: IndexMap<ty::Const<'tcx>, B::TyConstId>,
52 pub mir_consts: IndexMap<mir::Const<'tcx>, B::MirConstId>,
53 pub layouts: IndexMap<rustc_abi::Layout<'tcx>, B::Layout>,
54}
55
56impl<'tcx, B: Bridge> Default for Tables<'tcx, B> {
57 fn default() -> Self {
58 Self {
59 def_ids: IndexMap::default(),
60 alloc_ids: IndexMap::default(),
61 spans: IndexMap::default(),
62 types: IndexMap::default(),
63 instances: IndexMap::default(),
64 ty_consts: IndexMap::default(),
65 mir_consts: IndexMap::default(),
66 layouts: IndexMap::default(),
67 }
68 }
69}
70
71impl<'tcx, B: Bridge> Index<B::DefId> for Tables<'tcx, B> {
72 type Output = DefId;
73
74 #[inline(always)]
75 fn index(&self, index: B::DefId) -> &Self::Output {
76 &self.def_ids[index]
77 }
78}
79
80impl<'tcx, B: Bridge> Tables<'tcx, B> {
81 pub fn intern_ty(&mut self, ty: Ty<'tcx>) -> B::Ty {
82 self.types.create_or_fetch(ty)
83 }
84
85 pub fn intern_ty_const(&mut self, ct: ty::Const<'tcx>) -> B::TyConstId {
86 self.ty_consts.create_or_fetch(ct)
87 }
88
89 pub fn intern_mir_const(&mut self, constant: mir::Const<'tcx>) -> B::MirConstId {
90 self.mir_consts.create_or_fetch(constant)
91 }
92
93 pub fn create_def_id(&mut self, did: DefId) -> B::DefId {
94 self.def_ids.create_or_fetch(did)
95 }
96
97 pub fn create_alloc_id(&mut self, aid: AllocId) -> B::AllocId {
98 self.alloc_ids.create_or_fetch(aid)
99 }
100
101 pub fn create_span(&mut self, span: Span) -> B::Span {
102 self.spans.create_or_fetch(span)
103 }
104
105 pub fn instance_def(&mut self, instance: ty::Instance<'tcx>) -> B::InstanceDef {
106 self.instances.create_or_fetch(instance)
107 }
108
109 pub fn layout_id(&mut self, layout: rustc_abi::Layout<'tcx>) -> B::Layout {
110 self.layouts.create_or_fetch(layout)
111 }
112
113 pub fn crate_item(&mut self, did: rustc_span::def_id::DefId) -> B::CrateItem {
114 B::CrateItem::new(self.create_def_id(did))
115 }
116
117 pub fn adt_def(&mut self, did: rustc_span::def_id::DefId) -> B::AdtDef {
118 B::AdtDef::new(self.create_def_id(did))
119 }
120
121 pub fn foreign_module_def(&mut self, did: rustc_span::def_id::DefId) -> B::ForeignModuleDef {
122 B::ForeignModuleDef::new(self.create_def_id(did))
123 }
124
125 pub fn foreign_def(&mut self, did: rustc_span::def_id::DefId) -> B::ForeignDef {
126 B::ForeignDef::new(self.create_def_id(did))
127 }
128
129 pub fn fn_def(&mut self, did: rustc_span::def_id::DefId) -> B::FnDef {
130 B::FnDef::new(self.create_def_id(did))
131 }
132
133 pub fn closure_def(&mut self, did: rustc_span::def_id::DefId) -> B::ClosureDef {
134 B::ClosureDef::new(self.create_def_id(did))
135 }
136
137 pub fn coroutine_def(&mut self, did: rustc_span::def_id::DefId) -> B::CoroutineDef {
138 B::CoroutineDef::new(self.create_def_id(did))
139 }
140
141 pub fn coroutine_closure_def(
142 &mut self,
143 did: rustc_span::def_id::DefId,
144 ) -> B::CoroutineClosureDef {
145 B::CoroutineClosureDef::new(self.create_def_id(did))
146 }
147
148 pub fn alias_def(&mut self, did: rustc_span::def_id::DefId) -> B::AliasDef {
149 B::AliasDef::new(self.create_def_id(did))
150 }
151
152 pub fn param_def(&mut self, did: rustc_span::def_id::DefId) -> B::ParamDef {
153 B::ParamDef::new(self.create_def_id(did))
154 }
155
156 pub fn br_named_def(&mut self, did: rustc_span::def_id::DefId) -> B::BrNamedDef {
157 B::BrNamedDef::new(self.create_def_id(did))
158 }
159
160 pub fn trait_def(&mut self, did: rustc_span::def_id::DefId) -> B::TraitDef {
161 B::TraitDef::new(self.create_def_id(did))
162 }
163
164 pub fn generic_def(&mut self, did: rustc_span::def_id::DefId) -> B::GenericDef {
165 B::GenericDef::new(self.create_def_id(did))
166 }
167
168 pub fn const_def(&mut self, did: rustc_span::def_id::DefId) -> B::ConstDef {
169 B::ConstDef::new(self.create_def_id(did))
170 }
171
172 pub fn impl_def(&mut self, did: rustc_span::def_id::DefId) -> B::ImplDef {
173 B::ImplDef::new(self.create_def_id(did))
174 }
175
176 pub fn region_def(&mut self, did: rustc_span::def_id::DefId) -> B::RegionDef {
177 B::RegionDef::new(self.create_def_id(did))
178 }
179
180 pub fn coroutine_witness_def(
181 &mut self,
182 did: rustc_span::def_id::DefId,
183 ) -> B::CoroutineWitnessDef {
184 B::CoroutineWitnessDef::new(self.create_def_id(did))
185 }
186
187 pub fn assoc_def(&mut self, did: rustc_span::def_id::DefId) -> B::AssocDef {
188 B::AssocDef::new(self.create_def_id(did))
189 }
190
191 pub fn opaque_def(&mut self, did: rustc_span::def_id::DefId) -> B::OpaqueDef {
192 B::OpaqueDef::new(self.create_def_id(did))
193 }
194
195 pub fn prov(&mut self, aid: rustc_middle::mir::interpret::AllocId) -> B::Prov {
196 B::Prov::new(self.create_alloc_id(aid))
197 }
198
199 pub fn static_def(&mut self, did: rustc_span::def_id::DefId) -> B::StaticDef {
200 B::StaticDef::new(self.create_def_id(did))
201 }
202}
203
204pub trait Bridge: Sized {
207 type DefId: Cacheable;
208 type AllocId: Cacheable;
209 type Span: Cacheable;
210 type Ty: Cacheable;
211 type InstanceDef: Cacheable;
212 type TyConstId: Cacheable;
213 type MirConstId: Cacheable;
214 type Layout: Cacheable;
215
216 type Error: Error;
217 type CrateItem: CrateItem<Self>;
218 type AdtDef: AdtDef<Self>;
219 type ForeignModuleDef: ForeignModuleDef<Self>;
220 type ForeignDef: ForeignDef<Self>;
221 type FnDef: FnDef<Self>;
222 type ClosureDef: ClosureDef<Self>;
223 type CoroutineDef: CoroutineDef<Self>;
224 type CoroutineClosureDef: CoroutineClosureDef<Self>;
225 type AliasDef: AliasDef<Self>;
226 type ParamDef: ParamDef<Self>;
227 type BrNamedDef: BrNamedDef<Self>;
228 type TraitDef: TraitDef<Self>;
229 type GenericDef: GenericDef<Self>;
230 type ConstDef: ConstDef<Self>;
231 type ImplDef: ImplDef<Self>;
232 type RegionDef: RegionDef<Self>;
233 type CoroutineWitnessDef: CoroutineWitnessDef<Self>;
234 type AssocDef: AssocDef<Self>;
235 type OpaqueDef: OpaqueDef<Self>;
236 type Prov: Prov<Self>;
237 type StaticDef: StaticDef<Self>;
238
239 type Allocation: Allocation<Self>;
240}
241
242pub trait IndexedVal {
243 fn to_val(index: usize) -> Self;
244
245 fn to_index(&self) -> usize;
246}
247
248pub struct IndexMap<K, V> {
251 index_map: fx::FxIndexMap<K, V>,
252}
253
254impl<K, V> Default for IndexMap<K, V> {
255 fn default() -> Self {
256 Self { index_map: FxIndexMap::default() }
257 }
258}
259
260impl<K: PartialEq + Hash + Eq, V: Cacheable> IndexMap<K, V> {
261 pub fn create_or_fetch(&mut self, key: K) -> V {
262 let len = self.index_map.len();
263 let v = self.index_map.entry(key).or_insert(V::to_val(len));
264 *v
265 }
266}
267
268impl<K: PartialEq + Hash + Eq, V: Cacheable> Index<V> for IndexMap<K, V> {
269 type Output = K;
270
271 fn index(&self, index: V) -> &Self::Output {
272 let (k, v) = self.index_map.get_index(index.to_index()).unwrap();
273 assert_eq!(*v, index, "Provided value doesn't match with indexed value");
274 k
275 }
276}
277
278pub(crate) fn filter_def_ids<F, T>(tcx: TyCtxt<'_>, krate: CrateNum, mut func: F) -> Vec<T>
280where
281 F: FnMut(DefId) -> Option<T>,
282{
283 if krate == LOCAL_CRATE {
284 tcx.iter_local_def_id().filter_map(|did| func(did.to_def_id())).collect()
285 } else {
286 let num_definitions = tcx.num_extern_def_ids(krate);
287 (0..num_definitions)
288 .filter_map(move |i| {
289 let def_id = DefId { krate, index: rustc_span::def_id::DefIndex::from_usize(i) };
290 func(def_id)
291 })
292 .collect()
293 }
294}