@@ -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- }
182+ let opaque_type_values = mem:: take ( & mut infcx. inner . borrow_mut ( ) . opaque_types ) ;
194183
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- } ;
201-
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,18 @@ 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+ mir_def_id,
1309+ dummy_body_id,
1310+ param_env,
1311+ anon_ty,
1312+ locations. span ( body) ,
1313+ ) ) ;
13181314 debug ! (
13191315 "eq_opaque_type_and_type: \
13201316 instantiated output_ty={:?} \
1321- opaque_type_map={:#?} \
13221317 revealed_ty={:?}",
1323- output_ty, opaque_type_map , revealed_ty
1318+ output_ty, revealed_ty
13241319 ) ;
13251320
13261321 // Make sure that the inferred types are well-formed. I'm
@@ -1338,26 +1333,21 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
13381333 . eq ( output_ty, revealed_ty) ?,
13391334 ) ;
13401335
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-
13451336 debug ! ( "eq_opaque_type_and_type: equated" ) ;
13461337
1347- Ok ( InferOk { value : opaque_type_map , obligations : obligations. into_vec ( ) } )
1338+ Ok ( InferOk { value : ( ) , obligations : obligations. into_vec ( ) } )
13481339 } ,
13491340 || "input_output" . to_string ( ) ,
13501341 ) ,
13511342 ) ?;
13521343
1353- self . opaque_type_values . extend ( opaque_type_values) ;
1354-
13551344 let universal_region_relations = self . universal_region_relations ;
13561345
13571346 // Finally, if we instantiated the anon types successfully, we
13581347 // have to solve any bounds (e.g., `-> impl Iterator` needs to
13591348 // prove that `T: Iterator` where `T` is the type we
13601349 // instantiated it with).
1350+ let opaque_type_map = self . infcx . inner . borrow ( ) . opaque_types . clone ( ) ;
13611351 for ( opaque_type_key, opaque_decl) in opaque_type_map {
13621352 self . fully_perform_op (
13631353 locations,
0 commit comments