@@ -1253,51 +1253,58 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
12531253 & anon_ty,
12541254 locations. span ( body) ,
12551255 ) ) ;
1256-
1257- let revealed_ty_is_opaque = revealed_ty. is_impl_trait ( ) ;
1258-
12591256 debug ! (
12601257 "eq_opaque_type_and_type: \
12611258 instantiated output_ty={:?} \
12621259 opaque_type_map={:#?} \
1263- revealed_ty={:?} \
1264- revealed_ty_is_opaque={}",
1265- output_ty, opaque_type_map, revealed_ty, revealed_ty_is_opaque
1260+ revealed_ty={:?}",
1261+ output_ty, opaque_type_map, revealed_ty
12661262 ) ;
12671263 obligations. add ( infcx
12681264 . at ( & ObligationCause :: dummy ( ) , param_env)
12691265 . eq ( output_ty, revealed_ty) ?) ;
12701266
1271- // This is 'true' when we're using an existential
1272- // type without 'revelaing' it. For example, code like this:
1273- //
1274- // existential type Foo: Debug;
1275- // fn foo1() -> Foo { ... }
1276- // fn foo2() -> Foo { foo1() }
1277- //
1278- // In 'foo2', we're not revealing the type of 'Foo' - we're
1279- // just treating it as the opaque type. All of the constraints
1280- // in our 'opaque_type_map' apply to the concrete type,
1281- // not to the opaque type itself. Therefore, it's enough
1282- // to simply equate the output and opque 'revealed_type',
1283- // as we do above
1284- if revealed_ty_is_opaque {
1285- return Ok ( InferOk { value : None , obligations : obligations. into_vec ( ) } ) ;
1286- }
1287-
12881267 for ( & opaque_def_id, opaque_decl) in & opaque_type_map {
12891268 let opaque_defn_ty = tcx. type_of ( opaque_def_id) ;
12901269 let opaque_defn_ty = opaque_defn_ty. subst ( tcx, opaque_decl. substs ) ;
12911270 let opaque_defn_ty = renumber:: renumber_regions ( infcx, & opaque_defn_ty) ;
1271+ let concrete_is_opaque = infcx
1272+ . resolve_vars_if_possible ( & opaque_decl. concrete_ty ) . is_impl_trait ( ) ;
1273+
12921274 debug ! (
1293- "eq_opaque_type_and_type: concrete_ty={:?}={:?} opaque_defn_ty={:?}" ,
1275+ "eq_opaque_type_and_type: concrete_ty={:?}={:?} opaque_defn_ty={:?} \
1276+ concrete_is_opaque={}",
12941277 opaque_decl. concrete_ty,
12951278 infcx. resolve_vars_if_possible( & opaque_decl. concrete_ty) ,
1296- opaque_defn_ty
1279+ opaque_defn_ty,
1280+ concrete_is_opaque
12971281 ) ;
1298- obligations. add ( infcx
1299- . at ( & ObligationCause :: dummy ( ) , param_env)
1300- . eq ( opaque_decl. concrete_ty , opaque_defn_ty) ?) ;
1282+
1283+ // concrete_is_opaque is 'true' when we're using an existential
1284+ // type without 'revelaing' it. For example, code like this:
1285+ //
1286+ // existential type Foo: Debug;
1287+ // fn foo1() -> Foo { ... }
1288+ // fn foo2() -> Foo { foo1() }
1289+ //
1290+ // In 'foo2', we're not revealing the type of 'Foo' - we're
1291+ // just treating it as the opaque type.
1292+ //
1293+ // When this occurs, we do *not* want to try to equate
1294+ // the concrete type with the underlying defining type
1295+ // of the existential type - this will always fail, since
1296+ // the defining type of an existential type is always
1297+ // some other type (e.g. not itself)
1298+ // Essentially, none of the normal obligations apply here -
1299+ // we're just passing around some unknown opaque type,
1300+ // without actually looking at the underlying type it
1301+ // gets 'revealed' into
1302+
1303+ if !concrete_is_opaque {
1304+ obligations. add ( infcx
1305+ . at ( & ObligationCause :: dummy ( ) , param_env)
1306+ . eq ( opaque_decl. concrete_ty , opaque_defn_ty) ?) ;
1307+ }
13011308 }
13021309
13031310 debug ! ( "eq_opaque_type_and_type: equated" ) ;
0 commit comments