@@ -251,91 +251,100 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
251251 return self . tcx . ty_error ( e) ;
252252 }
253253
254- let definition_ty = instantiated_ty
255- . remap_generic_params_to_declaration_params ( opaque_type_key, self . tcx , false )
256- . ty ;
257-
258254 if let Err ( guar) =
259255 check_opaque_type_parameter_valid ( self . tcx , opaque_type_key, instantiated_ty. span )
260256 {
261257 return self . tcx . ty_error ( guar) ;
262258 }
263259
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 ;
296263
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 ,
304271 definition_ty,
305272 ) {
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| {
306319 infcx
307320 . err_ctxt ( )
308321 . report_mismatched_types (
309- & ObligationCause :: misc ( instantiated_ty . span , def_id) ,
322+ & ObligationCause :: misc ( definition_span , def_id) ,
310323 opaque_ty,
311324 definition_ty,
312325 err,
313326 )
314- . emit ( ) ;
315- }
327+ . emit ( )
328+ } ) ? ;
316329
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) ) ;
324335
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 ( ) ;
328339
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 ( ) ;
332343
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) )
339348 }
340349}
341350
0 commit comments