@@ -251,91 +251,100 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
251
251
return self . tcx . ty_error ( e) ;
252
252
}
253
253
254
- let definition_ty = instantiated_ty
255
- . remap_generic_params_to_declaration_params ( opaque_type_key, self . tcx , false )
256
- . ty ;
257
-
258
254
if let Err ( guar) =
259
255
check_opaque_type_parameter_valid ( self . tcx , opaque_type_key, instantiated_ty. span )
260
256
{
261
257
return self . tcx . ty_error ( guar) ;
262
258
}
263
259
264
- // Only check this for TAIT. RPIT already supports `tests/ui/impl-trait/nested-return-type2.rs`
265
- // on stable and we'd break that.
266
- let opaque_ty_hir = self . tcx . hir ( ) . expect_item ( opaque_type_key. def_id ) ;
267
- let OpaqueTyOrigin :: TyAlias { .. } = opaque_ty_hir. expect_opaque_ty ( ) . origin else {
268
- return definition_ty;
269
- } ;
270
- let def_id = opaque_type_key. def_id ;
271
- // This logic duplicates most of `check_opaque_meets_bounds`.
272
- // FIXME(oli-obk): Also do region checks here and then consider removing `check_opaque_meets_bounds` entirely.
273
- let param_env = self . tcx . param_env ( def_id) ;
274
- // HACK This bubble is required for this tests to pass:
275
- // nested-return-type2-tait2.rs
276
- // nested-return-type2-tait3.rs
277
- // FIXME(-Ztrait-solver=next): We probably should use `DefiningAnchor::Error`
278
- // and prepopulate this `InferCtxt` with known opaque values, rather than
279
- // using the `Bind` anchor here. For now it's fine.
280
- let infcx = self
281
- . tcx
282
- . infer_ctxt ( )
283
- . with_opaque_type_inference ( if self . next_trait_solver ( ) {
284
- DefiningAnchor :: Bind ( def_id)
285
- } else {
286
- DefiningAnchor :: Bubble
287
- } )
288
- . build ( ) ;
289
- let ocx = ObligationCtxt :: new ( & infcx) ;
290
- // Require the hidden type to be well-formed with only the generics of the opaque type.
291
- // Defining use functions may have more bounds than the opaque type, which is ok, as long as the
292
- // hidden type is well formed even without those bounds.
293
- let predicate = ty:: Binder :: dummy ( ty:: PredicateKind :: WellFormed ( definition_ty. into ( ) ) ) ;
294
-
295
- let id_substs = InternalSubsts :: identity_for_item ( self . tcx , def_id) ;
260
+ let definition_ty = instantiated_ty
261
+ . remap_generic_params_to_declaration_params ( opaque_type_key, self . tcx , false )
262
+ . ty ;
296
263
297
- // Require that the hidden type actually fulfills all the bounds of the opaque type, even without
298
- // the bounds that the function supplies .
299
- let opaque_ty = self . tcx . mk_opaque ( def_id . to_def_id ( ) , id_substs ) ;
300
- if let Err ( err ) = ocx . eq (
301
- & ObligationCause :: misc ( instantiated_ty . span , def_id ) ,
302
- param_env ,
303
- opaque_ty ,
264
+ // `definition_ty` does not live in of the current inference context,
265
+ // so lets make sure that we don't accidentally misuse our current `infcx` .
266
+ match check_opaque_type_well_formed (
267
+ self . tcx ,
268
+ self . next_trait_solver ( ) ,
269
+ opaque_type_key . def_id ,
270
+ instantiated_ty . span ,
304
271
definition_ty,
305
272
) {
273
+ Ok ( hidden_ty) => hidden_ty,
274
+ Err ( guar) => self . tcx . ty_error ( guar) ,
275
+ }
276
+ }
277
+ }
278
+
279
+ /// This logic duplicates most of `check_opaque_meets_bounds`.
280
+ /// FIXME(oli-obk): Also do region checks here and then consider removing
281
+ /// `check_opaque_meets_bounds` entirely.
282
+ fn check_opaque_type_well_formed < ' tcx > (
283
+ tcx : TyCtxt < ' tcx > ,
284
+ next_trait_solver : bool ,
285
+ def_id : LocalDefId ,
286
+ definition_span : Span ,
287
+ definition_ty : Ty < ' tcx > ,
288
+ ) -> Result < Ty < ' tcx > , ErrorGuaranteed > {
289
+ // Only check this for TAIT. RPIT already supports `tests/ui/impl-trait/nested-return-type2.rs`
290
+ // on stable and we'd break that.
291
+ let opaque_ty_hir = tcx. hir ( ) . expect_item ( def_id) ;
292
+ let OpaqueTyOrigin :: TyAlias { .. } = opaque_ty_hir. expect_opaque_ty ( ) . origin else {
293
+ return Ok ( definition_ty) ;
294
+ } ;
295
+ let param_env = tcx. param_env ( def_id) ;
296
+ // HACK This bubble is required for this tests to pass:
297
+ // nested-return-type2-tait2.rs
298
+ // nested-return-type2-tait3.rs
299
+ // FIXME(-Ztrait-solver=next): We probably should use `DefiningAnchor::Error`
300
+ // and prepopulate this `InferCtxt` with known opaque values, rather than
301
+ // using the `Bind` anchor here. For now it's fine.
302
+ let infcx = tcx
303
+ . infer_ctxt ( )
304
+ . with_next_trait_solver ( next_trait_solver)
305
+ . with_opaque_type_inference ( if next_trait_solver {
306
+ DefiningAnchor :: Bind ( def_id)
307
+ } else {
308
+ DefiningAnchor :: Bubble
309
+ } )
310
+ . build ( ) ;
311
+ let ocx = ObligationCtxt :: new ( & infcx) ;
312
+ let identity_substs = InternalSubsts :: identity_for_item ( tcx, def_id) ;
313
+
314
+ // Require that the hidden type actually fulfills all the bounds of the opaque type, even without
315
+ // the bounds that the function supplies.
316
+ let opaque_ty = tcx. mk_opaque ( def_id. to_def_id ( ) , identity_substs) ;
317
+ ocx. eq ( & ObligationCause :: misc ( definition_span, def_id) , param_env, opaque_ty, definition_ty)
318
+ . map_err ( |err| {
306
319
infcx
307
320
. err_ctxt ( )
308
321
. report_mismatched_types (
309
- & ObligationCause :: misc ( instantiated_ty . span , def_id) ,
322
+ & ObligationCause :: misc ( definition_span , def_id) ,
310
323
opaque_ty,
311
324
definition_ty,
312
325
err,
313
326
)
314
- . emit ( ) ;
315
- }
327
+ . emit ( )
328
+ } ) ? ;
316
329
317
- ocx. register_obligation ( Obligation :: misc (
318
- infcx. tcx ,
319
- instantiated_ty. span ,
320
- def_id,
321
- param_env,
322
- predicate,
323
- ) ) ;
330
+ // Require the hidden type to be well-formed with only the generics of the opaque type.
331
+ // Defining use functions may have more bounds than the opaque type, which is ok, as long as the
332
+ // hidden type is well formed even without those bounds.
333
+ let predicate = ty:: Binder :: dummy ( ty:: PredicateKind :: WellFormed ( definition_ty. into ( ) ) ) ;
334
+ ocx. register_obligation ( Obligation :: misc ( tcx, definition_span, def_id, param_env, predicate) ) ;
324
335
325
- // Check that all obligations are satisfied by the implementation's
326
- // version.
327
- let errors = ocx. select_all_or_error ( ) ;
336
+ // Check that all obligations are satisfied by the implementation's
337
+ // version.
338
+ let errors = ocx. select_all_or_error ( ) ;
328
339
329
- // This is still required for many(half of the tests in ui/type-alias-impl-trait)
330
- // tests to pass
331
- let _ = infcx. take_opaque_types ( ) ;
340
+ // This is still required for many(half of the tests in ui/type-alias-impl-trait)
341
+ // tests to pass
342
+ let _ = infcx. take_opaque_types ( ) ;
332
343
333
- if errors. is_empty ( ) {
334
- definition_ty
335
- } else {
336
- let reported = infcx. err_ctxt ( ) . report_fulfillment_errors ( & errors) ;
337
- self . tcx . ty_error ( reported)
338
- }
344
+ if errors. is_empty ( ) {
345
+ Ok ( definition_ty)
346
+ } else {
347
+ Err ( infcx. err_ctxt ( ) . report_fulfillment_errors ( & errors) )
339
348
}
340
349
}
341
350
0 commit comments