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