43
43
44
44
use ty:: { self , Ty , TyCtxt , TypeFoldable } ;
45
45
use ty:: fold:: TypeFolder ;
46
- use ty:: subst:: Substs ;
47
46
use util:: nodemap:: FxHashMap ;
48
- use hir:: def_id:: DefId ;
49
47
50
48
use std:: collections:: hash_map:: Entry ;
51
49
@@ -56,7 +54,6 @@ pub struct TypeFreshener<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
56
54
infcx : & ' a InferCtxt < ' a , ' gcx , ' tcx > ,
57
55
freshen_count : u32 ,
58
56
freshen_map : FxHashMap < ty:: InferTy , Ty < ' tcx > > ,
59
- closure_set : Vec < DefId > ,
60
57
}
61
58
62
59
impl < ' a , ' gcx , ' tcx > TypeFreshener < ' a , ' gcx , ' tcx > {
@@ -66,7 +63,6 @@ impl<'a, 'gcx, 'tcx> TypeFreshener<'a, 'gcx, 'tcx> {
66
63
infcx,
67
64
freshen_count : 0 ,
68
65
freshen_map : FxHashMap ( ) ,
69
- closure_set : vec ! [ ] ,
70
66
}
71
67
}
72
68
@@ -92,88 +88,6 @@ impl<'a, 'gcx, 'tcx> TypeFreshener<'a, 'gcx, 'tcx> {
92
88
}
93
89
}
94
90
}
95
-
96
- fn next_fresh < F > ( & mut self ,
97
- freshener : F )
98
- -> Ty < ' tcx >
99
- where F : FnOnce ( u32 ) -> ty:: InferTy ,
100
- {
101
- let index = self . freshen_count ;
102
- self . freshen_count += 1 ;
103
- self . infcx . tcx . mk_infer ( freshener ( index) )
104
- }
105
-
106
- fn freshen_closure_like < M , C > ( & mut self ,
107
- def_id : DefId ,
108
- substs : ty:: ClosureSubsts < ' tcx > ,
109
- t : Ty < ' tcx > ,
110
- markers : M ,
111
- combine : C )
112
- -> Ty < ' tcx >
113
- where M : FnOnce ( & mut Self ) -> ( Ty < ' tcx > , Ty < ' tcx > ) ,
114
- C : FnOnce ( & ' tcx Substs < ' tcx > ) -> Ty < ' tcx >
115
- {
116
- let tcx = self . infcx . tcx ;
117
-
118
- let closure_in_progress = self . infcx . in_progress_tables . map_or ( false , |tables| {
119
- tcx. hir . as_local_node_id ( def_id) . map_or ( false , |closure_id| {
120
- tables. borrow ( ) . local_id_root ==
121
- Some ( DefId :: local ( tcx. hir . node_to_hir_id ( closure_id) . owner ) )
122
- } )
123
- } ) ;
124
-
125
- if !closure_in_progress {
126
- // If this closure belongs to another infcx, its kind etc. were
127
- // fully inferred and its signature/kind are exactly what's listed
128
- // in its infcx. So we don't need to add the markers for them.
129
- return t. super_fold_with ( self ) ;
130
- }
131
-
132
- // We are encoding a closure in progress. Because we want our freshening
133
- // key to contain all inference information needed to make sense of our
134
- // value, we need to encode the closure signature and kind. The way
135
- // we do that is to add them as 2 variables to the closure substs,
136
- // basically because it's there (and nobody cares about adding extra stuff
137
- // to substs).
138
- //
139
- // This means the "freshened" closure substs ends up looking like
140
- // fresh_substs = [PARENT_SUBSTS* ; UPVARS* ; SIG_MARKER ; KIND_MARKER]
141
- let ( marker_1, marker_2) = if self . closure_set . contains ( & def_id) {
142
- // We found the closure def-id within its own signature. Just
143
- // leave a new freshened type - any matching operations would
144
- // have found and compared the exterior closure already to
145
- // get here.
146
- //
147
- // In that case, we already know what the signature would
148
- // be - the parent closure on the stack already contains a
149
- // "copy" of the signature, so there is no reason to encode
150
- // it again for injectivity. Just use a fresh type variable
151
- // to make everything comparable.
152
- //
153
- // For example (closure kinds omitted for clarity)
154
- // t=[closure FOO sig=[closure BAR sig=[closure FOO ..]]]
155
- // Would get encoded to
156
- // t=[closure FOO sig=[closure BAR sig=[closure FOO sig=$0]]]
157
- //
158
- // and we can decode by having
159
- // $0=[closure BAR {sig doesn't exist in decode}]
160
- // and get
161
- // t=[closure FOO]
162
- // sig[FOO] = [closure BAR]
163
- // sig[BAR] = [closure FOO]
164
- ( self . next_fresh ( ty:: FreshTy ) , self . next_fresh ( ty:: FreshTy ) )
165
- } else {
166
- self . closure_set . push ( def_id) ;
167
- let markers = markers ( self ) ;
168
- self . closure_set . pop ( ) ;
169
- markers
170
- } ;
171
-
172
- combine ( tcx. mk_substs (
173
- substs. substs . iter ( ) . map ( |k| k. fold_with ( self ) ) . chain (
174
- [ marker_1, marker_2] . iter ( ) . cloned ( ) . map ( From :: from)
175
- ) ) )
176
- }
177
91
}
178
92
179
93
impl < ' a , ' gcx , ' tcx > TypeFolder < ' gcx , ' tcx > for TypeFreshener < ' a , ' gcx , ' tcx > {
@@ -249,51 +163,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for TypeFreshener<'a, 'gcx, 'tcx> {
249
163
t
250
164
}
251
165
252
- ty:: TyClosure ( def_id, substs) => {
253
- self . freshen_closure_like (
254
- def_id, substs, t,
255
- |this| {
256
- // HACK: use a "random" integer type to mark the kind. Because
257
- // different closure kinds shouldn't get unified during
258
- // selection, the "subtyping" relationship (where any kind is
259
- // better than no kind) shouldn't matter here, just that the
260
- // types are different.
261
- let closure_kind = this. infcx . closure_kind ( def_id) ;
262
- let closure_kind_marker = match closure_kind {
263
- None => tcx. types . i8 ,
264
- Some ( ty:: ClosureKind :: Fn ) => tcx. types . i16 ,
265
- Some ( ty:: ClosureKind :: FnMut ) => tcx. types . i32 ,
266
- Some ( ty:: ClosureKind :: FnOnce ) => tcx. types . i64 ,
267
- } ;
268
-
269
- let closure_sig = this. infcx . fn_sig ( def_id) ;
270
- ( tcx. mk_fn_ptr ( closure_sig. fold_with ( this) ) ,
271
- closure_kind_marker)
272
- } ,
273
- |substs| tcx. mk_closure ( def_id, substs)
274
- )
275
- }
276
-
277
- ty:: TyGenerator ( def_id, substs, interior) => {
278
- self . freshen_closure_like (
279
- def_id, substs, t,
280
- |this| {
281
- let gen_sig = this. infcx . generator_sig ( def_id) . unwrap ( ) ;
282
- // FIXME: want to revise this strategy when generator
283
- // signatures can actually contain LBRs.
284
- let sig = this. tcx ( ) . no_late_bound_regions ( & gen_sig)
285
- . unwrap_or_else ( || {
286
- bug ! ( "late-bound regions in signature of {:?}" ,
287
- def_id)
288
- } ) ;
289
- ( sig. yield_ty , sig. return_ty ) . fold_with ( this)
290
- } ,
291
- |substs| {
292
- tcx. mk_generator ( def_id, ty:: ClosureSubsts { substs } , interior)
293
- }
294
- )
295
- }
296
-
166
+ ty:: TyGenerator ( ..) |
297
167
ty:: TyBool |
298
168
ty:: TyChar |
299
169
ty:: TyInt ( ..) |
@@ -314,6 +184,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for TypeFreshener<'a, 'gcx, 'tcx> {
314
184
ty:: TyProjection ( ..) |
315
185
ty:: TyForeign ( ..) |
316
186
ty:: TyParam ( ..) |
187
+ ty:: TyClosure ( ..) |
317
188
ty:: TyAnon ( ..) => {
318
189
t. super_fold_with ( self )
319
190
}
0 commit comments