1
1
use indexmap:: { IndexMap , IndexSet } ;
2
2
use rustc_hir:: { def:: DefKind , def_id:: DefId } ;
3
+ use rustc_span:: DUMMY_SP ;
3
4
4
5
use crate :: {
5
6
ctx:: { TranslatedItem , TranslationCtx } ,
@@ -9,6 +10,8 @@ use std::ops::{Deref, DerefMut};
9
10
10
11
pub ( crate ) use clone_map:: * ;
11
12
13
+ use self :: { dependency:: Dependency , ty_inv:: TyInvKind } ;
14
+
12
15
pub ( crate ) mod clone_map;
13
16
pub ( crate ) mod constant;
14
17
pub ( crate ) mod dependency;
@@ -21,13 +24,26 @@ pub(crate) mod signature;
21
24
pub ( crate ) mod term;
22
25
pub ( crate ) mod traits;
23
26
pub ( crate ) mod ty;
27
+ pub ( crate ) mod ty_inv;
28
+
29
+ #[ derive( Copy , Clone , PartialEq , Eq , Hash , PartialOrd , Ord , Debug ) ]
30
+ pub ( crate ) enum TransId {
31
+ Item ( DefId ) ,
32
+ TyInv ( TyInvKind ) ,
33
+ }
34
+
35
+ impl From < DefId > for TransId {
36
+ fn from ( def_id : DefId ) -> Self {
37
+ TransId :: Item ( def_id)
38
+ }
39
+ }
24
40
25
41
pub struct Why3Generator < ' tcx > {
26
42
ctx : TranslationCtx < ' tcx > ,
27
- dependencies : IndexMap < DefId , CloneSummary < ' tcx > > ,
28
- functions : IndexMap < DefId , TranslatedItem > ,
29
- translated_items : IndexSet < DefId > ,
30
- in_translation : Vec < IndexSet < DefId > > ,
43
+ dependencies : IndexMap < TransId , CloneSummary < ' tcx > > ,
44
+ functions : IndexMap < TransId , TranslatedItem > ,
45
+ translated_items : IndexSet < TransId > ,
46
+ in_translation : Vec < IndexSet < TransId > > ,
31
47
}
32
48
33
49
impl < ' tcx > Deref for Why3Generator < ' tcx > {
@@ -56,12 +72,13 @@ impl<'tcx> Why3Generator<'tcx> {
56
72
}
57
73
58
74
// Checks if we are allowed to recurse into
59
- fn safe_cycle ( & self , def_id : DefId ) -> bool {
60
- self . in_translation . last ( ) . map ( |l| l. contains ( & def_id ) ) . unwrap_or_default ( )
75
+ fn safe_cycle ( & self , trans_id : TransId ) -> bool {
76
+ self . in_translation . last ( ) . map ( |l| l. contains ( & trans_id ) ) . unwrap_or_default ( )
61
77
}
62
78
63
79
pub ( crate ) fn translate ( & mut self , def_id : DefId ) {
64
- if self . translated_items . contains ( & def_id) || self . safe_cycle ( def_id) {
80
+ let tid = def_id. into ( ) ;
81
+ if self . translated_items . contains ( & tid) || self . safe_cycle ( tid) {
65
82
return ;
66
83
}
67
84
debug ! ( "translating {:?}" , def_id) ;
@@ -72,17 +89,17 @@ impl<'tcx> Why3Generator<'tcx> {
72
89
ItemType :: Trait => {
73
90
self . start ( def_id) ;
74
91
let tr = self . translate_trait ( def_id) ;
75
- self . dependencies . insert ( def_id , CloneSummary :: new ( ) ) ;
76
- self . functions . insert ( def_id , tr) ;
92
+ self . dependencies . insert ( tid , CloneSummary :: new ( ) ) ;
93
+ self . functions . insert ( tid , tr) ;
77
94
self . finish ( def_id) ;
78
95
}
79
96
ItemType :: Impl => {
80
97
if self . tcx . impl_trait_ref ( def_id) . is_some ( ) {
81
98
self . start ( def_id) ;
82
99
let impl_ = traits:: lower_impl ( self , def_id) ;
83
100
84
- self . dependencies . insert ( def_id , CloneSummary :: new ( ) ) ;
85
- self . functions . insert ( def_id , TranslatedItem :: Impl { modl : impl_ } ) ;
101
+ self . dependencies . insert ( tid , CloneSummary :: new ( ) ) ;
102
+ self . functions . insert ( tid , TranslatedItem :: Impl { modl : impl_ } ) ;
86
103
self . finish ( def_id) ;
87
104
}
88
105
}
@@ -95,15 +112,15 @@ impl<'tcx> Why3Generator<'tcx> {
95
112
self . start ( def_id) ;
96
113
let ( modl, dependencies) = self . translate_assoc_ty ( def_id) ;
97
114
self . finish ( def_id) ;
98
- self . dependencies . insert ( def_id , dependencies) ;
99
- self . functions . insert ( def_id , TranslatedItem :: AssocTy { modl } ) ;
115
+ self . dependencies . insert ( tid , dependencies) ;
116
+ self . functions . insert ( tid , TranslatedItem :: AssocTy { modl } ) ;
100
117
}
101
118
ItemType :: Constant => {
102
119
self . start ( def_id) ;
103
120
let ( constant, dependencies) = self . translate_constant ( def_id) ;
104
121
self . finish ( def_id) ;
105
- self . dependencies . insert ( def_id , dependencies) ;
106
- self . functions . insert ( def_id , constant) ;
122
+ self . dependencies . insert ( tid , dependencies) ;
123
+ self . functions . insert ( tid , constant) ;
107
124
}
108
125
ItemType :: Type => {
109
126
let bg = self . binding_group ( def_id) . clone ( ) ;
@@ -116,7 +133,7 @@ impl<'tcx> Why3Generator<'tcx> {
116
133
self . finish ( * d) ;
117
134
}
118
135
119
- let repr = self . representative_type ( def_id) ;
136
+ let repr = self . representative_type ( def_id) . into ( ) ;
120
137
if let Some ( modl) = modl {
121
138
self . functions
122
139
. insert ( repr, TranslatedItem :: Type { modl, accessors : Default :: default ( ) } ) ;
@@ -148,31 +165,31 @@ impl<'tcx> Why3Generator<'tcx> {
148
165
debug ! ( "translating {:?} as logical" , def_id) ;
149
166
let ( stub, modl, proof_modl, has_axioms, deps) =
150
167
crate :: backend:: logic:: translate_logic_or_predicate ( self , def_id) ;
151
- self . dependencies . insert ( def_id, deps) ;
168
+ self . dependencies . insert ( def_id. into ( ) , deps) ;
152
169
153
170
TranslatedItem :: Logic { stub, interface, modl, proof_modl, has_axioms }
154
171
}
155
172
ItemType :: Closure => {
156
173
let ( ty_modl, modl) = program:: translate_closure ( self , def_id) ;
157
- self . dependencies . insert ( def_id, deps) ;
174
+ self . dependencies . insert ( def_id. into ( ) , deps) ;
158
175
159
176
TranslatedItem :: Closure { interface : vec ! [ ty_modl, interface] , modl }
160
177
}
161
178
ItemType :: Program => {
162
179
debug ! ( "translating {def_id:?} as program" ) ;
163
180
164
- self . dependencies . insert ( def_id, deps) ;
181
+ self . dependencies . insert ( def_id. into ( ) , deps) ;
165
182
let modl = program:: translate_function ( self , def_id) ;
166
183
TranslatedItem :: Program { interface, modl }
167
184
}
168
185
_ => unreachable ! ( ) ,
169
186
} ;
170
187
171
- self . functions . insert ( def_id, translated) ;
188
+ self . functions . insert ( def_id. into ( ) , translated) ;
172
189
}
173
190
174
191
pub ( crate ) fn translate_accessor ( & mut self , field_id : DefId ) {
175
- if !self . translated_items . insert ( field_id) {
192
+ if !self . translated_items . insert ( field_id. into ( ) ) {
176
193
return ;
177
194
}
178
195
@@ -187,30 +204,52 @@ impl<'tcx> Why3Generator<'tcx> {
187
204
self . translate ( adt_did) ;
188
205
189
206
let accessor = ty:: translate_accessor ( self , adt_did, variant_did, field_id) ;
190
- let repr_id = self . representative_type ( adt_did) ;
207
+ let repr_id: TransId = self . representative_type ( adt_did) . into ( ) ;
191
208
if let TranslatedItem :: Type { ref mut accessors, .. } = & mut self . functions [ & repr_id] {
192
209
accessors. entry ( variant_did) . or_default ( ) . insert ( field_id, accessor) ;
193
210
} ;
194
211
// self.types[&repr_id].accessors;
195
212
}
196
213
214
+ pub ( crate ) fn translate_tyinv ( & mut self , inv_kind : TyInvKind ) {
215
+ let tid = TransId :: TyInv ( inv_kind) ;
216
+ if self . dependencies . contains_key ( & tid) {
217
+ return ;
218
+ }
219
+
220
+ if let TyInvKind :: Adt ( adt_did) = inv_kind {
221
+ self . translate ( adt_did) ;
222
+ }
223
+
224
+ let ( modl, deps) = ty_inv:: build_inv_module ( self , inv_kind) ;
225
+ self . dependencies . insert ( tid, deps) ;
226
+ self . functions . insert ( tid, TranslatedItem :: TyInv { modl } ) ;
227
+ }
228
+
197
229
pub ( crate ) fn item ( & self , def_id : DefId ) -> Option < & TranslatedItem > {
198
- let def_id = if matches ! ( util:: item_type( * * * self , def_id) , ItemType :: Type ) {
230
+ let tid : TransId = if matches ! ( util:: item_type( * * * self , def_id) , ItemType :: Type ) {
199
231
self . representative_type ( def_id)
200
232
} else {
201
233
def_id
202
- } ;
203
- self . functions . get ( & def_id)
234
+ }
235
+ . into ( ) ;
236
+ self . functions . get ( & tid)
204
237
}
205
238
206
- pub ( crate ) fn modules ( self ) -> impl Iterator < Item = ( DefId , TranslatedItem ) > + ' tcx {
239
+ pub ( crate ) fn modules ( self ) -> impl Iterator < Item = ( TransId , TranslatedItem ) > + ' tcx {
207
240
self . functions . into_iter ( )
208
241
}
209
242
210
243
pub ( crate ) fn start_group ( & mut self , ids : IndexSet < DefId > ) {
211
244
assert ! ( !ids. is_empty( ) ) ;
245
+ let ids = ids. into_iter ( ) . map ( Into :: into) . collect ( ) ;
212
246
if self . in_translation . iter ( ) . rev ( ) . any ( |s| !s. is_disjoint ( & ids) ) {
213
- let span = self . def_span ( ids. first ( ) . unwrap ( ) ) ;
247
+ let span = if let TransId :: Item ( def_id) = ids. first ( ) . unwrap ( ) {
248
+ self . def_span ( def_id)
249
+ } else {
250
+ DUMMY_SP
251
+ } ;
252
+
214
253
self . in_translation . push ( ids) ;
215
254
216
255
self . crash_and_error (
@@ -229,7 +268,8 @@ impl<'tcx> Why3Generator<'tcx> {
229
268
230
269
// Indicate we have finished translating a given id
231
270
pub ( crate ) fn finish ( & mut self , def_id : DefId ) {
232
- if !self . in_translation . last_mut ( ) . unwrap ( ) . remove ( & def_id) {
271
+ let tid = def_id. into ( ) ;
272
+ if !self . in_translation . last_mut ( ) . unwrap ( ) . remove ( & tid) {
233
273
self . crash_and_error (
234
274
self . def_span ( def_id) ,
235
275
& format ! ( "{:?} is not in translation" , def_id) ,
@@ -240,10 +280,14 @@ impl<'tcx> Why3Generator<'tcx> {
240
280
self . in_translation . pop ( ) ;
241
281
}
242
282
243
- self . translated_items . insert ( def_id ) ;
283
+ self . translated_items . insert ( tid ) ;
244
284
}
245
285
246
- pub ( crate ) fn dependencies ( & self , def_id : DefId ) -> Option < & CloneSummary < ' tcx > > {
247
- self . dependencies . get ( & def_id)
286
+ pub ( crate ) fn dependencies ( & self , key : Dependency < ' tcx > ) -> Option < & CloneSummary < ' tcx > > {
287
+ let tid = match key {
288
+ Dependency :: TyInv ( ty) => TransId :: TyInv ( TyInvKind :: from_ty ( ty) ) ,
289
+ _ => key. did ( ) . map ( |( def_id, _) | TransId :: Item ( def_id) ) ?,
290
+ } ;
291
+ self . dependencies . get ( & tid)
248
292
}
249
293
}
0 commit comments