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 ;
108use rustc_data_structures:: fx;
@@ -14,14 +12,18 @@ use rustc_middle::mir::interpret::AllocId;
1412use rustc_middle:: ty:: TyCtxt ;
1513use rustc_span:: def_id:: { CrateNum , DefId } ;
1614use rustc_span:: Span ;
15+ use stable_mir:: ty:: IndexedVal ;
1716use stable_mir:: CompilerError ;
17+ use std:: fmt:: Debug ;
18+ use std:: hash:: Hash ;
19+ use std:: ops:: { ControlFlow , Index } ;
1820
1921impl < ' tcx > Index < stable_mir:: DefId > for Tables < ' tcx > {
2022 type Output = DefId ;
2123
2224 #[ inline( always) ]
2325 fn index ( & self , index : stable_mir:: DefId ) -> & Self :: Output {
24- & self . def_ids . get_index ( index. 0 ) . unwrap ( ) . 0
26+ & self . def_ids [ index]
2527 }
2628}
2729
@@ -30,7 +32,7 @@ impl<'tcx> Index<stable_mir::ty::Span> for Tables<'tcx> {
3032
3133 #[ inline( always) ]
3234 fn index ( & self , index : stable_mir:: ty:: Span ) -> & Self :: Output {
33- & self . spans . get_index ( index. 0 ) . unwrap ( ) . 0
35+ & self . spans [ index]
3436 }
3537}
3638
@@ -96,33 +98,15 @@ impl<'tcx> Tables<'tcx> {
9698 }
9799
98100 fn create_def_id ( & mut self , did : DefId ) -> stable_mir:: DefId {
99- if let Some ( i) = self . def_ids . get ( & did) {
100- return * i;
101- } else {
102- let id = self . def_ids . len ( ) ;
103- self . def_ids . insert ( did, stable_mir:: DefId ( id) ) ;
104- stable_mir:: DefId ( id)
105- }
101+ self . def_ids . create_or_fetch ( did)
106102 }
107103
108104 fn create_alloc_id ( & mut self , aid : AllocId ) -> stable_mir:: AllocId {
109- if let Some ( i) = self . alloc_ids . get ( & aid) {
110- return * i;
111- } else {
112- let id = self . def_ids . len ( ) ;
113- self . alloc_ids . insert ( aid, stable_mir:: AllocId ( id) ) ;
114- stable_mir:: AllocId ( id)
115- }
105+ self . alloc_ids . create_or_fetch ( aid)
116106 }
117107
118108 pub ( crate ) fn create_span ( & mut self , span : Span ) -> stable_mir:: ty:: Span {
119- if let Some ( i) = self . spans . get ( & span) {
120- return * i;
121- } else {
122- let id = self . spans . len ( ) ;
123- self . spans . insert ( span, stable_mir:: ty:: Span ( id) ) ;
124- stable_mir:: ty:: Span ( id)
125- }
109+ self . spans . create_or_fetch ( span)
126110 }
127111}
128112
@@ -134,9 +118,9 @@ pub fn run(tcx: TyCtxt<'_>, f: impl FnOnce()) {
134118 stable_mir:: run (
135119 Tables {
136120 tcx,
137- def_ids : fx:: FxIndexMap :: default ( ) ,
138- alloc_ids : fx:: FxIndexMap :: default ( ) ,
139- spans : fx:: FxIndexMap :: default ( ) ,
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 ( ) } ,
140124 types : vec ! [ ] ,
141125 } ,
142126 f,
@@ -201,3 +185,29 @@ where
201185 } )
202186 }
203187}
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