33//! For that, we define APIs that will temporarily be public to 3P that exposes rustc internal APIs
44//! until stable MIR is complete.
55
6- use std:: ops:: { ControlFlow , Index } ;
7-
86use crate :: rustc_internal;
97use crate :: rustc_smir:: Tables ;
8+ use rustc_data_structures:: fx;
109use rustc_driver:: { Callbacks , Compilation , RunCompiler } ;
1110use rustc_interface:: { interface, Queries } ;
1211use rustc_middle:: mir:: interpret:: AllocId ;
1312use rustc_middle:: ty:: TyCtxt ;
1413use rustc_span:: def_id:: { CrateNum , DefId } ;
1514use rustc_span:: Span ;
15+ use stable_mir:: ty:: IndexedVal ;
1616use stable_mir:: CompilerError ;
17+ use std:: fmt:: Debug ;
18+ use std:: hash:: Hash ;
19+ use std:: ops:: { ControlFlow , Index } ;
1720
1821impl < ' tcx > Index < stable_mir:: DefId > for Tables < ' tcx > {
1922 type Output = DefId ;
2023
2124 #[ inline( always) ]
2225 fn index ( & self , index : stable_mir:: DefId ) -> & Self :: Output {
23- & self . def_ids [ index. 0 ]
26+ & self . def_ids [ index]
2427 }
2528}
2629
@@ -29,7 +32,7 @@ impl<'tcx> Index<stable_mir::ty::Span> for Tables<'tcx> {
2932
3033 #[ inline( always) ]
3134 fn index ( & self , index : stable_mir:: ty:: Span ) -> & Self :: Output {
32- & self . spans [ index. 0 ]
35+ & self . spans [ index]
3336 }
3437}
3538
@@ -95,36 +98,15 @@ impl<'tcx> Tables<'tcx> {
9598 }
9699
97100 fn create_def_id ( & mut self , did : DefId ) -> stable_mir:: DefId {
98- // FIXME: this becomes inefficient when we have too many ids
99- for ( i, & d) in self . def_ids . iter ( ) . enumerate ( ) {
100- if d == did {
101- return stable_mir:: DefId ( i) ;
102- }
103- }
104- let id = self . def_ids . len ( ) ;
105- self . def_ids . push ( did) ;
106- stable_mir:: DefId ( id)
101+ self . def_ids . create_or_fetch ( did)
107102 }
108103
109104 fn create_alloc_id ( & mut self , aid : AllocId ) -> stable_mir:: AllocId {
110- // FIXME: this becomes inefficient when we have too many ids
111- if let Some ( i) = self . alloc_ids . iter ( ) . position ( |a| * a == aid) {
112- return stable_mir:: AllocId ( i) ;
113- } ;
114- let id = self . def_ids . len ( ) ;
115- self . alloc_ids . push ( aid) ;
116- stable_mir:: AllocId ( id)
105+ self . alloc_ids . create_or_fetch ( aid)
117106 }
118107
119108 pub ( crate ) fn create_span ( & mut self , span : Span ) -> stable_mir:: ty:: Span {
120- for ( i, & sp) in self . spans . iter ( ) . enumerate ( ) {
121- if sp == span {
122- return stable_mir:: ty:: Span ( i) ;
123- }
124- }
125- let id = self . spans . len ( ) ;
126- self . spans . push ( span) ;
127- stable_mir:: ty:: Span ( id)
109+ self . spans . create_or_fetch ( span)
128110 }
129111}
130112
@@ -134,7 +116,13 @@ pub fn crate_num(item: &stable_mir::Crate) -> CrateNum {
134116
135117pub fn run ( tcx : TyCtxt < ' _ > , f : impl FnOnce ( ) ) {
136118 stable_mir:: run (
137- Tables { tcx, def_ids : vec ! [ ] , alloc_ids : vec ! [ ] , spans : vec ! [ ] , types : vec ! [ ] } ,
119+ Tables {
120+ tcx,
121+ def_ids : rustc_internal:: IndexMap { index_map : fx:: FxIndexMap :: default ( ) } ,
122+ alloc_ids : rustc_internal:: IndexMap { index_map : fx:: FxIndexMap :: default ( ) } ,
123+ spans : rustc_internal:: IndexMap { index_map : fx:: FxIndexMap :: default ( ) } ,
124+ types : vec ! [ ] ,
125+ } ,
138126 f,
139127 ) ;
140128}
@@ -197,3 +185,29 @@ where
197185 } )
198186 }
199187}
188+
189+ /// Simmilar to rustc's `FxIndexMap`, `IndexMap` with extra
190+ /// safety features added.
191+ pub struct IndexMap < K , V > {
192+ index_map : fx:: FxIndexMap < K , V > ,
193+ }
194+
195+ impl < K : PartialEq + Hash + Eq , V : Copy + Debug + PartialEq + IndexedVal > IndexMap < K , V > {
196+ pub fn create_or_fetch ( & mut self , key : K ) -> V {
197+ let len = self . index_map . len ( ) ;
198+ let v = self . index_map . entry ( key) . or_insert ( V :: to_val ( len) ) ;
199+ * v
200+ }
201+ }
202+
203+ impl < K : PartialEq + Hash + Eq , V : Copy + Debug + PartialEq + IndexedVal > Index < V >
204+ for IndexMap < K , V >
205+ {
206+ type Output = K ;
207+
208+ fn index ( & self , index : V ) -> & Self :: Output {
209+ let ( k, v) = self . index_map . get_index ( index. to_index ( ) ) . unwrap ( ) ;
210+ assert_eq ! ( * v, index, "Provided value doesn't match with indexed value" ) ;
211+ k
212+ }
213+ }
0 commit comments