@@ -179,54 +179,55 @@ pub(crate) fn type_check<'mir, 'tcx>(
179179 liveness:: generate ( & mut cx, body, elements, flow_inits, move_data, location_table) ;
180180
181181 translate_outlives_facts ( & mut cx) ;
182- let mut opaque_type_values = cx. opaque_type_values ;
183-
184- for ( _, revealed_ty) in & mut opaque_type_values {
185- * revealed_ty = infcx. resolve_vars_if_possible ( * revealed_ty) ;
186- if revealed_ty. has_infer_types_or_consts ( ) {
187- infcx. tcx . sess . delay_span_bug (
188- body. span ,
189- & format ! ( "could not resolve {:#?}" , revealed_ty. kind( ) ) ,
190- ) ;
191- * revealed_ty = infcx. tcx . ty_error ( ) ;
192- }
193- }
194-
195- opaque_type_values. retain ( |( opaque_type_key, resolved_ty) | {
196- let concrete_is_opaque = if let ty:: Opaque ( def_id, _) = resolved_ty. kind ( ) {
197- * def_id == opaque_type_key. def_id
198- } else {
199- false
200- } ;
182+ let opaque_type_values = mem:: take ( & mut infcx. inner . borrow_mut ( ) . opaque_types ) ;
201183
202- if concrete_is_opaque {
203- // We're using an opaque `impl Trait` type without
204- // 'revealing' it. For example, code like this:
205- //
206- // type Foo = impl Debug;
207- // fn foo1() -> Foo { ... }
208- // fn foo2() -> Foo { foo1() }
209- //
210- // In `foo2`, we're not revealing the type of `Foo` - we're
211- // just treating it as the opaque type.
212- //
213- // When this occurs, we do *not* want to try to equate
214- // the concrete type with the underlying defining type
215- // of the opaque type - this will always fail, since
216- // the defining type of an opaque type is always
217- // some other type (e.g. not itself)
218- // Essentially, none of the normal obligations apply here -
219- // we're just passing around some unknown opaque type,
220- // without actually looking at the underlying type it
221- // gets 'revealed' into
222- debug ! (
223- "eq_opaque_type_and_type: non-defining use of {:?}" ,
224- opaque_type_key. def_id,
225- ) ;
226- }
227- !concrete_is_opaque
228- } ) ;
229184 opaque_type_values
185+ . into_iter ( )
186+ . filter_map ( |( opaque_type_key, decl) | {
187+ let mut revealed_ty = infcx. resolve_vars_if_possible ( decl. concrete_ty ) ;
188+ if revealed_ty. has_infer_types_or_consts ( ) {
189+ infcx. tcx . sess . delay_span_bug (
190+ body. span ,
191+ & format ! ( "could not resolve {:#?}" , revealed_ty. kind( ) ) ,
192+ ) ;
193+ revealed_ty = infcx. tcx . ty_error ( ) ;
194+ }
195+ let concrete_is_opaque = if let ty:: Opaque ( def_id, _) = revealed_ty. kind ( ) {
196+ * def_id == opaque_type_key. def_id
197+ } else {
198+ false
199+ } ;
200+
201+ if concrete_is_opaque {
202+ // We're using an opaque `impl Trait` type without
203+ // 'revealing' it. For example, code like this:
204+ //
205+ // type Foo = impl Debug;
206+ // fn foo1() -> Foo { ... }
207+ // fn foo2() -> Foo { foo1() }
208+ //
209+ // In `foo2`, we're not revealing the type of `Foo` - we're
210+ // just treating it as the opaque type.
211+ //
212+ // When this occurs, we do *not* want to try to equate
213+ // the concrete type with the underlying defining type
214+ // of the opaque type - this will always fail, since
215+ // the defining type of an opaque type is always
216+ // some other type (e.g. not itself)
217+ // Essentially, none of the normal obligations apply here -
218+ // we're just passing around some unknown opaque type,
219+ // without actually looking at the underlying type it
220+ // gets 'revealed' into
221+ debug ! (
222+ "eq_opaque_type_and_type: non-defining use of {:?}" ,
223+ opaque_type_key. def_id,
224+ ) ;
225+ None
226+ } else {
227+ Some ( ( opaque_type_key, revealed_ty) )
228+ }
229+ } )
230+ . collect ( )
230231 } ,
231232 ) ;
232233
@@ -865,7 +866,6 @@ struct TypeChecker<'a, 'tcx> {
865866 reported_errors : FxHashSet < ( Ty < ' tcx > , Span ) > ,
866867 borrowck_context : & ' a mut BorrowCheckContext < ' a , ' tcx > ,
867868 universal_region_relations : & ' a UniversalRegionRelations < ' tcx > ,
868- opaque_type_values : VecMap < OpaqueTypeKey < ' tcx > , Ty < ' tcx > > ,
869869}
870870
871871struct BorrowCheckContext < ' a , ' tcx > {
@@ -1025,7 +1025,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
10251025 borrowck_context,
10261026 reported_errors : Default :: default ( ) ,
10271027 universal_region_relations,
1028- opaque_type_values : VecMap :: default ( ) ,
10291028 } ;
10301029 checker. check_user_type_annotations ( ) ;
10311030 checker
@@ -1289,10 +1288,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
12891288 let body = self . body ;
12901289 let mir_def_id = body. source . def_id ( ) . expect_local ( ) ;
12911290
1292- let mut opaque_type_values = VecMap :: new ( ) ;
1293-
12941291 debug ! ( "eq_opaque_type_and_type: mir_def_id={:?}" , mir_def_id) ;
1295- let opaque_type_map = self . fully_perform_op (
1292+ self . fully_perform_op (
12961293 locations,
12971294 category,
12981295 CustomTypeOp :: new (
@@ -1307,20 +1304,17 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
13071304 // to `Box<?T>`, returning an `opaque_type_map` mapping `{Foo<T> -> ?T}`.
13081305 // (Note that the key of the map is both the def-id of `Foo` along with
13091306 // any generic parameters.)
1310- let ( output_ty, opaque_type_map) =
1311- obligations. add ( infcx. instantiate_opaque_types (
1312- mir_def_id,
1313- dummy_body_id,
1314- param_env,
1315- anon_ty,
1316- locations. span ( body) ,
1317- ) ) ;
1307+ let output_ty = obligations. add ( infcx. instantiate_opaque_types (
1308+ dummy_body_id,
1309+ param_env,
1310+ anon_ty,
1311+ locations. span ( body) ,
1312+ ) ) ;
13181313 debug ! (
13191314 "eq_opaque_type_and_type: \
13201315 instantiated output_ty={:?} \
1321- opaque_type_map={:#?} \
13221316 revealed_ty={:?}",
1323- output_ty, opaque_type_map , revealed_ty
1317+ output_ty, revealed_ty
13241318 ) ;
13251319
13261320 // Make sure that the inferred types are well-formed. I'm
@@ -1338,48 +1332,38 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
13381332 . eq ( output_ty, revealed_ty) ?,
13391333 ) ;
13401334
1341- for & ( opaque_type_key, opaque_decl) in & opaque_type_map {
1342- opaque_type_values. insert ( opaque_type_key, opaque_decl. concrete_ty ) ;
1343- }
1344-
13451335 debug ! ( "eq_opaque_type_and_type: equated" ) ;
13461336
1347- Ok ( InferOk {
1348- value : Some ( opaque_type_map) ,
1349- obligations : obligations. into_vec ( ) ,
1350- } )
1337+ Ok ( InferOk { value : ( ) , obligations : obligations. into_vec ( ) } )
13511338 } ,
13521339 || "input_output" . to_string ( ) ,
13531340 ) ,
13541341 ) ?;
13551342
1356- self . opaque_type_values . extend ( opaque_type_values) ;
1357-
13581343 let universal_region_relations = self . universal_region_relations ;
13591344
13601345 // Finally, if we instantiated the anon types successfully, we
13611346 // have to solve any bounds (e.g., `-> impl Iterator` needs to
13621347 // prove that `T: Iterator` where `T` is the type we
13631348 // instantiated it with).
1364- if let Some ( opaque_type_map) = opaque_type_map {
1365- for ( opaque_type_key, opaque_decl) in opaque_type_map {
1366- self . fully_perform_op (
1367- locations,
1368- ConstraintCategory :: OpaqueType ,
1369- CustomTypeOp :: new (
1370- |infcx| {
1371- infcx. constrain_opaque_type (
1372- opaque_type_key,
1373- & opaque_decl,
1374- GenerateMemberConstraints :: IfNoStaticBound ,
1375- universal_region_relations,
1376- ) ;
1377- Ok ( InferOk { value : ( ) , obligations : vec ! [ ] } )
1378- } ,
1379- || "opaque_type_map" . to_string ( ) ,
1380- ) ,
1381- ) ?;
1382- }
1349+ let opaque_type_map = self . infcx . inner . borrow ( ) . opaque_types . clone ( ) ;
1350+ for ( opaque_type_key, opaque_decl) in opaque_type_map {
1351+ self . fully_perform_op (
1352+ locations,
1353+ ConstraintCategory :: OpaqueType ,
1354+ CustomTypeOp :: new (
1355+ |infcx| {
1356+ infcx. constrain_opaque_type (
1357+ opaque_type_key,
1358+ & opaque_decl,
1359+ GenerateMemberConstraints :: IfNoStaticBound ,
1360+ universal_region_relations,
1361+ ) ;
1362+ Ok ( InferOk { value : ( ) , obligations : vec ! [ ] } )
1363+ } ,
1364+ || "opaque_type_map" . to_string ( ) ,
1365+ ) ,
1366+ ) ?;
13831367 }
13841368 Ok ( ( ) )
13851369 }
0 commit comments