@@ -158,7 +158,7 @@ pub(crate) fn type_check<'mir, 'tcx>(
158158 constraints : & mut constraints,
159159 } ;
160160
161- type_check_internal (
161+ let opaque_type_values = type_check_internal (
162162 infcx,
163163 mir_def_id,
164164 param_env,
@@ -173,10 +173,11 @@ pub(crate) fn type_check<'mir, 'tcx>(
173173 liveness:: generate ( & mut cx, body, elements, flow_inits, move_data, location_table) ;
174174
175175 translate_outlives_facts ( & mut cx) ;
176+ cx. opaque_type_values
176177 } ,
177178 ) ;
178179
179- MirTypeckResults { constraints, universal_region_relations }
180+ MirTypeckResults { constraints, universal_region_relations, opaque_type_values }
180181}
181182
182183fn type_check_internal < ' a , ' tcx , R > (
@@ -189,7 +190,7 @@ fn type_check_internal<'a, 'tcx, R>(
189190 implicit_region_bound : ty:: Region < ' tcx > ,
190191 borrowck_context : & ' a mut BorrowCheckContext < ' a , ' tcx > ,
191192 universal_region_relations : & ' a UniversalRegionRelations < ' tcx > ,
192- mut extra : impl FnMut ( & mut TypeChecker < ' a , ' tcx > ) -> R ,
193+ extra : impl FnOnce ( TypeChecker < ' a , ' tcx > ) -> R ,
193194) -> R {
194195 let mut checker = TypeChecker :: new (
195196 infcx,
@@ -212,7 +213,7 @@ fn type_check_internal<'a, 'tcx, R>(
212213 checker. typeck_mir ( body) ;
213214 }
214215
215- extra ( & mut checker)
216+ extra ( checker)
216217}
217218
218219fn translate_outlives_facts ( typeck : & mut TypeChecker < ' _ , ' _ > ) {
@@ -799,6 +800,7 @@ struct TypeChecker<'a, 'tcx> {
799800 reported_errors : FxHashSet < ( Ty < ' tcx > , Span ) > ,
800801 borrowck_context : & ' a mut BorrowCheckContext < ' a , ' tcx > ,
801802 universal_region_relations : & ' a UniversalRegionRelations < ' tcx > ,
803+ opaque_type_values : FxHashMap < DefId , ty:: ResolvedOpaqueTy < ' tcx > > ,
802804}
803805
804806struct BorrowCheckContext < ' a , ' tcx > {
@@ -812,6 +814,7 @@ struct BorrowCheckContext<'a, 'tcx> {
812814crate struct MirTypeckResults < ' tcx > {
813815 crate constraints : MirTypeckRegionConstraints < ' tcx > ,
814816 crate universal_region_relations : Rc < UniversalRegionRelations < ' tcx > > ,
817+ crate opaque_type_values : FxHashMap < DefId , ty:: ResolvedOpaqueTy < ' tcx > > ,
815818}
816819
817820/// A collection of region constraints that must be satisfied for the
@@ -958,6 +961,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
958961 borrowck_context,
959962 reported_errors : Default :: default ( ) ,
960963 universal_region_relations,
964+ opaque_type_values : FxHashMap :: default ( ) ,
961965 } ;
962966 checker. check_user_type_annotations ( ) ;
963967 checker
@@ -1195,6 +1199,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
11951199 let tcx = infcx. tcx ;
11961200 let param_env = self . param_env ;
11971201 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+
11981205 debug ! ( "eq_opaque_type_and_type: mir_def_id={:?}" , self . mir_def_id) ;
11991206 let opaque_type_map = self . fully_perform_op (
12001207 locations,
@@ -1226,47 +1233,65 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
12261233 ) ;
12271234
12281235 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) ;
12351258
12361259 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,
12431262 ) ;
12441263
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-
12651264 if !concrete_is_opaque {
12661265 obligations. add (
12671266 infcx
12681267 . 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,
12701295 ) ;
12711296 }
12721297 }
@@ -1282,6 +1307,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
12821307 ) ,
12831308 ) ?;
12841309
1310+ self . opaque_type_values . extend ( opaque_type_values) ;
1311+
12851312 let universal_region_relations = self . universal_region_relations ;
12861313
12871314 // Finally, if we instantiated the anon types successfully, we
0 commit comments