@@ -159,7 +159,7 @@ pub(crate) fn type_check<'tcx>(
159159 constraints : & mut constraints,
160160 } ;
161161
162- type_check_internal (
162+ let opaque_type_values = type_check_internal (
163163 infcx,
164164 mir_def_id,
165165 param_env,
@@ -174,10 +174,11 @@ pub(crate) fn type_check<'tcx>(
174174 liveness:: generate ( & mut cx, body, elements, flow_inits, move_data, location_table) ;
175175
176176 translate_outlives_facts ( & mut cx) ;
177+ cx. opaque_type_values
177178 } ,
178179 ) ;
179180
180- MirTypeckResults { constraints, universal_region_relations }
181+ MirTypeckResults { constraints, universal_region_relations, opaque_type_values }
181182}
182183
183184fn type_check_internal < ' a , ' tcx , R > (
@@ -190,7 +191,7 @@ fn type_check_internal<'a, 'tcx, R>(
190191 implicit_region_bound : ty:: Region < ' tcx > ,
191192 borrowck_context : & ' a mut BorrowCheckContext < ' a , ' tcx > ,
192193 universal_region_relations : & ' a UniversalRegionRelations < ' tcx > ,
193- mut extra : impl FnMut ( & mut TypeChecker < ' a , ' tcx > ) -> R ,
194+ extra : impl FnOnce ( TypeChecker < ' a , ' tcx > ) -> R ,
194195) -> R {
195196 let mut checker = TypeChecker :: new (
196197 infcx,
@@ -213,7 +214,7 @@ fn type_check_internal<'a, 'tcx, R>(
213214 checker. typeck_mir ( body) ;
214215 }
215216
216- extra ( & mut checker)
217+ extra ( checker)
217218}
218219
219220fn translate_outlives_facts ( typeck : & mut TypeChecker < ' _ , ' _ > ) {
@@ -800,6 +801,7 @@ struct TypeChecker<'a, 'tcx> {
800801 reported_errors : FxHashSet < ( Ty < ' tcx > , Span ) > ,
801802 borrowck_context : & ' a mut BorrowCheckContext < ' a , ' tcx > ,
802803 universal_region_relations : & ' a UniversalRegionRelations < ' tcx > ,
804+ opaque_type_values : FxHashMap < DefId , ty:: ResolvedOpaqueTy < ' tcx > > ,
803805}
804806
805807struct BorrowCheckContext < ' a , ' tcx > {
@@ -813,6 +815,7 @@ struct BorrowCheckContext<'a, 'tcx> {
813815crate struct MirTypeckResults < ' tcx > {
814816 crate constraints : MirTypeckRegionConstraints < ' tcx > ,
815817 crate universal_region_relations : Rc < UniversalRegionRelations < ' tcx > > ,
818+ crate opaque_type_values : FxHashMap < DefId , ty:: ResolvedOpaqueTy < ' tcx > > ,
816819}
817820
818821/// A collection of region constraints that must be satisfied for the
@@ -959,6 +962,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
959962 borrowck_context,
960963 reported_errors : Default :: default ( ) ,
961964 universal_region_relations,
965+ opaque_type_values : FxHashMap :: default ( ) ,
962966 } ;
963967 checker. check_user_type_annotations ( ) ;
964968 checker
@@ -1196,6 +1200,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
11961200 let tcx = infcx. tcx ;
11971201 let param_env = self . param_env ;
11981202 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+
11991206 debug ! ( "eq_opaque_type_and_type: mir_def_id={:?}" , self . mir_def_id) ;
12001207 let opaque_type_map = self . fully_perform_op (
12011208 locations,
@@ -1227,47 +1234,65 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
12271234 ) ;
12281235
12291236 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) ;
12361259
12371260 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,
12441263 ) ;
12451264
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-
12661265 if !concrete_is_opaque {
12671266 obligations. add (
12681267 infcx
12691268 . 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,
12711296 ) ;
12721297 }
12731298 }
@@ -1283,6 +1308,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
12831308 ) ,
12841309 ) ?;
12851310
1311+ self . opaque_type_values . extend ( opaque_type_values) ;
1312+
12861313 let universal_region_relations = self . universal_region_relations ;
12871314
12881315 // Finally, if we instantiated the anon types successfully, we
0 commit comments