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