@@ -18,7 +18,7 @@ use rustc_infer::infer::outlives::env::RegionBoundPairs;
18
18
use rustc_infer:: infer:: region_constraints:: RegionConstraintData ;
19
19
use rustc_infer:: infer:: type_variable:: { TypeVariableOrigin , TypeVariableOriginKind } ;
20
20
use rustc_infer:: infer:: {
21
- BoundRegion , BoundRegionConversionTime , InferCtxt , NllRegionVariableOrigin ,
21
+ BoundRegion , BoundRegionConversionTime , InferCtxt , NllRegionVariableOrigin , TypeTrace ,
22
22
} ;
23
23
use rustc_middle:: mir:: tcx:: PlaceTy ;
24
24
use rustc_middle:: mir:: visit:: { NonMutatingUseContext , PlaceContext , Visitor } ;
@@ -245,6 +245,47 @@ pub(crate) fn type_check<'mir, 'tcx>(
245
245
}
246
246
} ) ;
247
247
248
+ // If the hidden type is the opaque type itself (with potentially different args), we can
249
+ // check that the hidden type's args are the same, without worrying about defining new
250
+ // opaque types or producing new obligations beyond lifetime obligations
251
+ if let ty:: Alias ( ty:: Opaque , alias_ty) = hidden_type. ty . kind ( )
252
+ && alias_ty. def_id == opaque_type_key. def_id . into ( )
253
+ {
254
+ if let Err ( terr) = checker. eq_args (
255
+ opaque_type_key. args ,
256
+ alias_ty. args ,
257
+ Locations :: All ( hidden_type. span ) ,
258
+ ConstraintCategory :: OpaqueType ,
259
+ ) {
260
+ // Recursive opaque type: An opaque type `Foo<T>` has a hidden type of `Foo<Vec<T>>`
261
+ // This can happen with recursive function calls.
262
+ let cause = ObligationCause :: dummy_with_span ( hidden_type. span ) ;
263
+ let guar = infcx
264
+ . err_ctxt ( )
265
+ . report_and_explain_type_error (
266
+ TypeTrace :: types (
267
+ & cause,
268
+ true ,
269
+ Ty :: new_opaque (
270
+ infcx. tcx ,
271
+ opaque_type_key. def_id . into ( ) ,
272
+ opaque_type_key. args ,
273
+ ) ,
274
+ hidden_type. ty ,
275
+ ) ,
276
+ terr,
277
+ )
278
+ . emit ( ) ;
279
+ return (
280
+ opaque_type_key,
281
+ OpaqueHiddenType {
282
+ ty : Ty :: new_error ( infcx. tcx , guar) ,
283
+ span : hidden_type. span ,
284
+ } ,
285
+ ) ;
286
+ }
287
+ }
288
+
248
289
( opaque_type_key, hidden_type)
249
290
} )
250
291
. collect ( ) ;
0 commit comments