@@ -179,54 +179,55 @@ pub(crate) fn type_check<'mir, 'tcx>(
179
179
liveness:: generate ( & mut cx, body, elements, flow_inits, move_data, location_table) ;
180
180
181
181
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 ) ;
201
183
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
- } ) ;
229
184
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 ( )
230
231
} ,
231
232
) ;
232
233
@@ -865,7 +866,6 @@ struct TypeChecker<'a, 'tcx> {
865
866
reported_errors : FxHashSet < ( Ty < ' tcx > , Span ) > ,
866
867
borrowck_context : & ' a mut BorrowCheckContext < ' a , ' tcx > ,
867
868
universal_region_relations : & ' a UniversalRegionRelations < ' tcx > ,
868
- opaque_type_values : VecMap < OpaqueTypeKey < ' tcx > , Ty < ' tcx > > ,
869
869
}
870
870
871
871
struct BorrowCheckContext < ' a , ' tcx > {
@@ -1025,7 +1025,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
1025
1025
borrowck_context,
1026
1026
reported_errors : Default :: default ( ) ,
1027
1027
universal_region_relations,
1028
- opaque_type_values : VecMap :: default ( ) ,
1029
1028
} ;
1030
1029
checker. check_user_type_annotations ( ) ;
1031
1030
checker
@@ -1289,10 +1288,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
1289
1288
let body = self . body ;
1290
1289
let mir_def_id = body. source . def_id ( ) . expect_local ( ) ;
1291
1290
1292
- let mut opaque_type_values = VecMap :: new ( ) ;
1293
-
1294
1291
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 (
1296
1293
locations,
1297
1294
category,
1298
1295
CustomTypeOp :: new (
@@ -1307,20 +1304,17 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
1307
1304
// to `Box<?T>`, returning an `opaque_type_map` mapping `{Foo<T> -> ?T}`.
1308
1305
// (Note that the key of the map is both the def-id of `Foo` along with
1309
1306
// 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
+ ) ) ;
1318
1313
debug ! (
1319
1314
"eq_opaque_type_and_type: \
1320
1315
instantiated output_ty={:?} \
1321
- opaque_type_map={:#?} \
1322
1316
revealed_ty={:?}",
1323
- output_ty, opaque_type_map , revealed_ty
1317
+ output_ty, revealed_ty
1324
1318
) ;
1325
1319
1326
1320
// Make sure that the inferred types are well-formed. I'm
@@ -1338,48 +1332,38 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
1338
1332
. eq ( output_ty, revealed_ty) ?,
1339
1333
) ;
1340
1334
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
-
1345
1335
debug ! ( "eq_opaque_type_and_type: equated" ) ;
1346
1336
1347
- Ok ( InferOk {
1348
- value : Some ( opaque_type_map) ,
1349
- obligations : obligations. into_vec ( ) ,
1350
- } )
1337
+ Ok ( InferOk { value : ( ) , obligations : obligations. into_vec ( ) } )
1351
1338
} ,
1352
1339
|| "input_output" . to_string ( ) ,
1353
1340
) ,
1354
1341
) ?;
1355
1342
1356
- self . opaque_type_values . extend ( opaque_type_values) ;
1357
-
1358
1343
let universal_region_relations = self . universal_region_relations ;
1359
1344
1360
1345
// Finally, if we instantiated the anon types successfully, we
1361
1346
// have to solve any bounds (e.g., `-> impl Iterator` needs to
1362
1347
// prove that `T: Iterator` where `T` is the type we
1363
1348
// 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
+ ) ?;
1383
1367
}
1384
1368
Ok ( ( ) )
1385
1369
}
0 commit comments