4343
4444use ty:: { self , Ty , TyCtxt , TypeFoldable } ;
4545use ty:: fold:: TypeFolder ;
46- use ty:: subst:: Substs ;
4746use util:: nodemap:: FxHashMap ;
48- use hir:: def_id:: DefId ;
4947
5048use std:: collections:: hash_map:: Entry ;
5149
@@ -56,7 +54,6 @@ pub struct TypeFreshener<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
5654 infcx : & ' a InferCtxt < ' a , ' gcx , ' tcx > ,
5755 freshen_count : u32 ,
5856 freshen_map : FxHashMap < ty:: InferTy , Ty < ' tcx > > ,
59- closure_set : Vec < DefId > ,
6057}
6158
6259impl < ' a , ' gcx , ' tcx > TypeFreshener < ' a , ' gcx , ' tcx > {
@@ -66,7 +63,6 @@ impl<'a, 'gcx, 'tcx> TypeFreshener<'a, 'gcx, 'tcx> {
6663 infcx,
6764 freshen_count : 0 ,
6865 freshen_map : FxHashMap ( ) ,
69- closure_set : vec ! [ ] ,
7066 }
7167 }
7268
@@ -92,88 +88,6 @@ impl<'a, 'gcx, 'tcx> TypeFreshener<'a, 'gcx, 'tcx> {
9288 }
9389 }
9490 }
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- }
17791}
17892
17993impl < ' 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> {
249163 t
250164 }
251165
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 ( ..) |
297167 ty:: TyBool |
298168 ty:: TyChar |
299169 ty:: TyInt ( ..) |
@@ -314,6 +184,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for TypeFreshener<'a, 'gcx, 'tcx> {
314184 ty:: TyProjection ( ..) |
315185 ty:: TyForeign ( ..) |
316186 ty:: TyParam ( ..) |
187+ ty:: TyClosure ( ..) |
317188 ty:: TyAnon ( ..) => {
318189 t. super_fold_with ( self )
319190 }
0 commit comments