@@ -7,7 +7,7 @@ use super::FnCtxt;
77use rustc:: hir:: map:: Map ;
88use rustc:: middle:: region:: { self , YieldData } ;
99use rustc:: ty:: { self , Ty } ;
10- use rustc_data_structures:: fx:: FxHashMap ;
10+ use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
1111use rustc_hir as hir;
1212use rustc_hir:: def:: { CtorKind , DefKind , Res } ;
1313use rustc_hir:: def_id:: DefId ;
@@ -160,33 +160,39 @@ pub fn resolve_interior<'a, 'tcx>(
160160
161161 debug ! ( "types in generator {:?}, span = {:?}" , types, body. value. span) ;
162162
163- // Replace all regions inside the generator interior with late bound regions
164- // Note that each region slot in the types gets a new fresh late bound region,
165- // which means that none of the regions inside relate to any other, even if
166- // typeck had previously found constraints that would cause them to be related.
167163 let mut counter = 0 ;
168- let fold_types: Vec < _ > = types. iter ( ) . map ( |( t, _) | t. ty ) . collect ( ) ;
169- let folded_types = fcx. tcx . fold_regions ( & fold_types, & mut false , |_, current_depth| {
170- counter += 1 ;
171- fcx. tcx . mk_region ( ty:: ReLateBound ( current_depth, ty:: BrAnon ( counter) ) )
172- } ) ;
173-
174- // Store the generator types and spans into the tables for this generator.
175- let types = types
164+ let mut captured_tys = FxHashSet :: default ( ) ;
165+ let type_causes: Vec < _ > = types
176166 . into_iter ( )
177- . zip ( & folded_types)
178- . map ( |( ( mut interior_cause, _) , ty) | {
179- interior_cause. ty = ty;
180- interior_cause
167+ . filter_map ( |( mut cause, _) | {
168+ // Erase regions and canonicalize late-bound regions to deduplicate as many types as we
169+ // can.
170+ let erased = fcx. tcx . erase_regions ( & cause. ty ) ;
171+ if captured_tys. insert ( erased) {
172+ // Replace all regions inside the generator interior with late bound regions.
173+ // Note that each region slot in the types gets a new fresh late bound region,
174+ // which means that none of the regions inside relate to any other, even if
175+ // typeck had previously found constraints that would cause them to be related.
176+ let folded = fcx. tcx . fold_regions ( & erased, & mut false , |_, current_depth| {
177+ counter += 1 ;
178+ fcx. tcx . mk_region ( ty:: ReLateBound ( current_depth, ty:: BrAnon ( counter) ) )
179+ } ) ;
180+
181+ cause. ty = folded;
182+ Some ( cause)
183+ } else {
184+ None
185+ }
181186 } )
182187 . collect ( ) ;
183- visitor. fcx . inh . tables . borrow_mut ( ) . generator_interior_types = types;
184-
185- // Extract type components
186- let type_list = fcx. tcx . mk_type_list ( folded_types. iter ( ) ) ;
187188
189+ // Extract type components to build the witness type.
190+ let type_list = fcx. tcx . mk_type_list ( type_causes. iter ( ) . map ( |cause| cause. ty ) ) ;
188191 let witness = fcx. tcx . mk_generator_witness ( ty:: Binder :: bind ( type_list) ) ;
189192
193+ // Store the generator types and spans into the tables for this generator.
194+ visitor. fcx . inh . tables . borrow_mut ( ) . generator_interior_types = type_causes;
195+
190196 debug ! (
191197 "types in generator after region replacement {:?}, span = {:?}" ,
192198 witness, body. value. span
0 commit comments