@@ -159,7 +159,7 @@ pub(crate) fn type_check<'tcx>(
159
159
constraints : & mut constraints,
160
160
} ;
161
161
162
- type_check_internal (
162
+ let opaque_type_values = type_check_internal (
163
163
infcx,
164
164
mir_def_id,
165
165
param_env,
@@ -174,10 +174,11 @@ pub(crate) fn type_check<'tcx>(
174
174
liveness:: generate ( & mut cx, body, elements, flow_inits, move_data, location_table) ;
175
175
176
176
translate_outlives_facts ( & mut cx) ;
177
+ cx. opaque_type_values
177
178
} ,
178
179
) ;
179
180
180
- MirTypeckResults { constraints, universal_region_relations }
181
+ MirTypeckResults { constraints, universal_region_relations, opaque_type_values }
181
182
}
182
183
183
184
fn type_check_internal < ' a , ' tcx , R > (
@@ -190,7 +191,7 @@ fn type_check_internal<'a, 'tcx, R>(
190
191
implicit_region_bound : ty:: Region < ' tcx > ,
191
192
borrowck_context : & ' a mut BorrowCheckContext < ' a , ' tcx > ,
192
193
universal_region_relations : & ' a UniversalRegionRelations < ' tcx > ,
193
- mut extra : impl FnMut ( & mut TypeChecker < ' a , ' tcx > ) -> R ,
194
+ extra : impl FnOnce ( TypeChecker < ' a , ' tcx > ) -> R ,
194
195
) -> R {
195
196
let mut checker = TypeChecker :: new (
196
197
infcx,
@@ -213,7 +214,7 @@ fn type_check_internal<'a, 'tcx, R>(
213
214
checker. typeck_mir ( body) ;
214
215
}
215
216
216
- extra ( & mut checker)
217
+ extra ( checker)
217
218
}
218
219
219
220
fn translate_outlives_facts ( typeck : & mut TypeChecker < ' _ , ' _ > ) {
@@ -800,6 +801,7 @@ struct TypeChecker<'a, 'tcx> {
800
801
reported_errors : FxHashSet < ( Ty < ' tcx > , Span ) > ,
801
802
borrowck_context : & ' a mut BorrowCheckContext < ' a , ' tcx > ,
802
803
universal_region_relations : & ' a UniversalRegionRelations < ' tcx > ,
804
+ opaque_type_values : FxHashMap < DefId , ty:: ResolvedOpaqueTy < ' tcx > > ,
803
805
}
804
806
805
807
struct BorrowCheckContext < ' a , ' tcx > {
@@ -813,6 +815,7 @@ struct BorrowCheckContext<'a, 'tcx> {
813
815
crate struct MirTypeckResults < ' tcx > {
814
816
crate constraints : MirTypeckRegionConstraints < ' tcx > ,
815
817
crate universal_region_relations : Rc < UniversalRegionRelations < ' tcx > > ,
818
+ crate opaque_type_values : FxHashMap < DefId , ty:: ResolvedOpaqueTy < ' tcx > > ,
816
819
}
817
820
818
821
/// A collection of region constraints that must be satisfied for the
@@ -959,6 +962,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
959
962
borrowck_context,
960
963
reported_errors : Default :: default ( ) ,
961
964
universal_region_relations,
965
+ opaque_type_values : FxHashMap :: default ( ) ,
962
966
} ;
963
967
checker. check_user_type_annotations ( ) ;
964
968
checker
@@ -1196,6 +1200,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
1196
1200
let tcx = infcx. tcx ;
1197
1201
let param_env = self . param_env ;
1198
1202
let body = self . body ;
1203
+ let concrete_opaque_types = & tcx. typeck_tables_of ( anon_owner_def_id) . concrete_opaque_types ;
1204
+ let mut opaque_type_values = Vec :: new ( ) ;
1205
+
1199
1206
debug ! ( "eq_opaque_type_and_type: mir_def_id={:?}" , self . mir_def_id) ;
1200
1207
let opaque_type_map = self . fully_perform_op (
1201
1208
locations,
@@ -1227,47 +1234,65 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
1227
1234
) ;
1228
1235
1229
1236
for ( & opaque_def_id, opaque_decl) in & opaque_type_map {
1230
- let opaque_defn_ty = tcx. type_of ( opaque_def_id) ;
1231
- let opaque_defn_ty = opaque_defn_ty. subst ( tcx, opaque_decl. substs ) ;
1232
- let opaque_defn_ty = renumber:: renumber_regions ( infcx, & opaque_defn_ty) ;
1233
- let concrete_is_opaque = infcx
1234
- . resolve_vars_if_possible ( & opaque_decl. concrete_ty )
1235
- . is_impl_trait ( ) ;
1237
+ let resolved_ty = infcx. resolve_vars_if_possible ( & opaque_decl. concrete_ty ) ;
1238
+ let concrete_is_opaque = if let ty:: Opaque ( def_id, _) = resolved_ty. kind {
1239
+ def_id == opaque_def_id
1240
+ } else {
1241
+ false
1242
+ } ;
1243
+ let opaque_defn_ty = match concrete_opaque_types. get ( & opaque_def_id) {
1244
+ None => {
1245
+ assert ! (
1246
+ concrete_is_opaque,
1247
+ "Non-defining use of {:?} with revealed type" ,
1248
+ opaque_def_id,
1249
+ ) ;
1250
+ continue ;
1251
+ }
1252
+ Some ( opaque_defn_ty) => opaque_defn_ty,
1253
+ } ;
1254
+ debug ! ( "opaque_defn_ty = {:?}" , opaque_defn_ty) ;
1255
+ let subst_opaque_defn_ty =
1256
+ opaque_defn_ty. concrete_type . subst ( tcx, opaque_decl. substs ) ;
1257
+ let renumbered_opaque_defn_ty =
1258
+ renumber:: renumber_regions ( infcx, & subst_opaque_defn_ty) ;
1236
1259
1237
1260
debug ! (
1238
- "eq_opaque_type_and_type: concrete_ty={:?}={:?} opaque_defn_ty={:?} \
1239
- concrete_is_opaque={}",
1240
- opaque_decl. concrete_ty,
1241
- infcx. resolve_vars_if_possible( & opaque_decl. concrete_ty) ,
1242
- opaque_defn_ty,
1243
- concrete_is_opaque
1261
+ "eq_opaque_type_and_type: concrete_ty={:?}={:?} opaque_defn_ty={:?}" ,
1262
+ opaque_decl. concrete_ty, resolved_ty, renumbered_opaque_defn_ty,
1244
1263
) ;
1245
1264
1246
- // concrete_is_opaque is `true` when we're using an opaque `impl Trait`
1247
- // type without 'revealing' it. For example, code like this:
1248
- //
1249
- // type Foo = impl Debug;
1250
- // fn foo1() -> Foo { ... }
1251
- // fn foo2() -> Foo { foo1() }
1252
- //
1253
- // In `foo2`, we're not revealing the type of `Foo` - we're
1254
- // just treating it as the opaque type.
1255
- //
1256
- // When this occurs, we do *not* want to try to equate
1257
- // the concrete type with the underlying defining type
1258
- // of the opaque type - this will always fail, since
1259
- // the defining type of an opaque type is always
1260
- // some other type (e.g. not itself)
1261
- // Essentially, none of the normal obligations apply here -
1262
- // we're just passing around some unknown opaque type,
1263
- // without actually looking at the underlying type it
1264
- // gets 'revealed' into
1265
-
1266
1265
if !concrete_is_opaque {
1267
1266
obligations. add (
1268
1267
infcx
1269
1268
. at ( & ObligationCause :: dummy ( ) , param_env)
1270
- . eq ( opaque_decl. concrete_ty , opaque_defn_ty) ?,
1269
+ . eq ( opaque_decl. concrete_ty , renumbered_opaque_defn_ty) ?,
1270
+ ) ;
1271
+ opaque_type_values
1272
+ . push ( ( opaque_def_id, ty:: ResolvedOpaqueTy { ..* opaque_defn_ty } ) ) ;
1273
+ } else {
1274
+ // We're using an opaque `impl Trait` type without
1275
+ // 'revealing' it. For example, code like this:
1276
+ //
1277
+ // type Foo = impl Debug;
1278
+ // fn foo1() -> Foo { ... }
1279
+ // fn foo2() -> Foo { foo1() }
1280
+ //
1281
+ // In `foo2`, we're not revealing the type of `Foo` - we're
1282
+ // just treating it as the opaque type.
1283
+ //
1284
+ // When this occurs, we do *not* want to try to equate
1285
+ // the concrete type with the underlying defining type
1286
+ // of the opaque type - this will always fail, since
1287
+ // the defining type of an opaque type is always
1288
+ // some other type (e.g. not itself)
1289
+ // Essentially, none of the normal obligations apply here -
1290
+ // we're just passing around some unknown opaque type,
1291
+ // without actually looking at the underlying type it
1292
+ // gets 'revealed' into
1293
+ debug ! (
1294
+ "eq_opaque_type_and_type: non-defining use of {:?}" ,
1295
+ opaque_def_id,
1271
1296
) ;
1272
1297
}
1273
1298
}
@@ -1283,6 +1308,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
1283
1308
) ,
1284
1309
) ?;
1285
1310
1311
+ self . opaque_type_values . extend ( opaque_type_values) ;
1312
+
1286
1313
let universal_region_relations = self . universal_region_relations ;
1287
1314
1288
1315
// Finally, if we instantiated the anon types successfully, we
0 commit comments