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