@@ -1253,51 +1253,58 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
1253
1253
& anon_ty,
1254
1254
locations. span ( body) ,
1255
1255
) ) ;
1256
-
1257
- let revealed_ty_is_opaque = revealed_ty. is_impl_trait ( ) ;
1258
-
1259
1256
debug ! (
1260
1257
"eq_opaque_type_and_type: \
1261
1258
instantiated output_ty={:?} \
1262
1259
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
1266
1262
) ;
1267
1263
obligations. add ( infcx
1268
1264
. at ( & ObligationCause :: dummy ( ) , param_env)
1269
1265
. eq ( output_ty, revealed_ty) ?) ;
1270
1266
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
-
1288
1267
for ( & opaque_def_id, opaque_decl) in & opaque_type_map {
1289
1268
let opaque_defn_ty = tcx. type_of ( opaque_def_id) ;
1290
1269
let opaque_defn_ty = opaque_defn_ty. subst ( tcx, opaque_decl. substs ) ;
1291
1270
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
+
1292
1274
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={}",
1294
1277
opaque_decl. concrete_ty,
1295
1278
infcx. resolve_vars_if_possible( & opaque_decl. concrete_ty) ,
1296
- opaque_defn_ty
1279
+ opaque_defn_ty,
1280
+ concrete_is_opaque
1297
1281
) ;
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
+ }
1301
1308
}
1302
1309
1303
1310
debug ! ( "eq_opaque_type_and_type: equated" ) ;
0 commit comments