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