3
3
//! For that, we define APIs that will temporarily be public to 3P that exposes rustc internal APIs
4
4
//! until stable MIR is complete.
5
5
6
- use std:: ops:: { ControlFlow , Index } ;
7
-
8
6
use crate :: rustc_internal;
9
7
use crate :: rustc_smir:: Tables ;
10
8
use rustc_data_structures:: fx;
@@ -14,14 +12,18 @@ use rustc_middle::mir::interpret::AllocId;
14
12
use rustc_middle:: ty:: TyCtxt ;
15
13
use rustc_span:: def_id:: { CrateNum , DefId } ;
16
14
use rustc_span:: Span ;
15
+ use stable_mir:: ty:: IndexToVal ;
17
16
use stable_mir:: CompilerError ;
17
+ use std:: fmt:: Debug ;
18
+ use std:: hash:: Hash ;
19
+ use std:: ops:: { ControlFlow , Index } ;
18
20
19
21
impl < ' tcx > Index < stable_mir:: DefId > for Tables < ' tcx > {
20
22
type Output = DefId ;
21
23
22
24
#[ inline( always) ]
23
25
fn index ( & self , index : stable_mir:: DefId ) -> & Self :: Output {
24
- & self . def_ids . get_index ( index. 0 ) . unwrap ( ) . 0
26
+ & self . def_ids . get_index_and_assert ( index. 0 , index )
25
27
}
26
28
}
27
29
@@ -30,7 +32,7 @@ impl<'tcx> Index<stable_mir::ty::Span> for Tables<'tcx> {
30
32
31
33
#[ inline( always) ]
32
34
fn index ( & self , index : stable_mir:: ty:: Span ) -> & Self :: Output {
33
- & self . spans . get_index ( index. 0 ) . unwrap ( ) . 0
35
+ & self . spans . get_index_and_assert ( index. 0 , index )
34
36
}
35
37
}
36
38
@@ -96,33 +98,15 @@ impl<'tcx> Tables<'tcx> {
96
98
}
97
99
98
100
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 . entry ( did)
106
102
}
107
103
108
104
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 . entry ( aid)
116
106
}
117
107
118
108
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 . entry ( span)
126
110
}
127
111
}
128
112
@@ -134,9 +118,9 @@ pub fn run(tcx: TyCtxt<'_>, f: impl FnOnce()) {
134
118
stable_mir:: run (
135
119
Tables {
136
120
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 ( ) } ,
140
124
types : vec ! [ ] ,
141
125
} ,
142
126
f,
@@ -201,3 +185,26 @@ where
201
185
} )
202
186
}
203
187
}
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 + IndexToVal > IndexMap < K , V > {
196
+ /// Because we are using values as indexes, this first get's the
197
+ /// key using index of the value provided, then asserts that value
198
+ /// we got from IndexMap is equal to one we provided.
199
+ pub fn get_index_and_assert ( & self , index : usize , value : V ) -> & K {
200
+ let ( k, v) = self . index_map . get_index ( index) . unwrap ( ) ;
201
+ assert_eq ! ( * v, value, "Provided value doesn't match with indexed value" ) ;
202
+ k
203
+ }
204
+
205
+ pub fn entry ( & mut self , key : K ) -> V {
206
+ let len = self . index_map . len ( ) ;
207
+ let v = self . index_map . entry ( key) . or_insert ( V :: to_val ( len) ) ;
208
+ * v
209
+ }
210
+ }
0 commit comments