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 ;
8
+ use rustc_data_structures:: fx;
10
9
use rustc_driver:: { Callbacks , Compilation , RunCompiler } ;
11
10
use rustc_interface:: { interface, Queries } ;
12
11
use rustc_middle:: mir:: interpret:: AllocId ;
13
12
use rustc_middle:: ty:: TyCtxt ;
14
13
use rustc_span:: def_id:: { CrateNum , DefId } ;
15
14
use rustc_span:: Span ;
15
+ use stable_mir:: ty:: IndexedVal ;
16
16
use stable_mir:: CompilerError ;
17
+ use std:: fmt:: Debug ;
18
+ use std:: hash:: Hash ;
19
+ use std:: ops:: { ControlFlow , Index } ;
17
20
18
21
impl < ' tcx > Index < stable_mir:: DefId > for Tables < ' tcx > {
19
22
type Output = DefId ;
20
23
21
24
#[ inline( always) ]
22
25
fn index ( & self , index : stable_mir:: DefId ) -> & Self :: Output {
23
- & self . def_ids [ index. 0 ]
26
+ & self . def_ids [ index]
24
27
}
25
28
}
26
29
@@ -29,7 +32,7 @@ impl<'tcx> Index<stable_mir::ty::Span> for Tables<'tcx> {
29
32
30
33
#[ inline( always) ]
31
34
fn index ( & self , index : stable_mir:: ty:: Span ) -> & Self :: Output {
32
- & self . spans [ index. 0 ]
35
+ & self . spans [ index]
33
36
}
34
37
}
35
38
@@ -95,36 +98,15 @@ impl<'tcx> Tables<'tcx> {
95
98
}
96
99
97
100
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)
107
102
}
108
103
109
104
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)
117
106
}
118
107
119
108
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)
128
110
}
129
111
}
130
112
@@ -134,7 +116,13 @@ pub fn crate_num(item: &stable_mir::Crate) -> CrateNum {
134
116
135
117
pub fn run ( tcx : TyCtxt < ' _ > , f : impl FnOnce ( ) ) {
136
118
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
+ } ,
138
126
f,
139
127
) ;
140
128
}
@@ -197,3 +185,29 @@ where
197
185
} )
198
186
}
199
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 + 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