@@ -61,7 +61,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
6161 pub ( crate ) fn infer_opaque_types (
6262 & self ,
6363 infcx : & InferCtxt < ' tcx > ,
64- opaque_ty_decls : FxIndexMap < OpaqueTypeKey < ' tcx > , ( OpaqueHiddenType < ' tcx > , OpaqueTyOrigin ) > ,
64+ opaque_ty_decls : FxIndexMap < OpaqueTypeKey < ' tcx > , OpaqueHiddenType < ' tcx > > ,
6565 ) -> FxIndexMap < LocalDefId , OpaqueHiddenType < ' tcx > > {
6666 let mut result: FxIndexMap < LocalDefId , OpaqueHiddenType < ' tcx > > = FxIndexMap :: default ( ) ;
6767
@@ -72,7 +72,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
7272 . collect ( ) ;
7373 debug ! ( ?member_constraints) ;
7474
75- for ( opaque_type_key, ( concrete_type, origin ) ) in opaque_ty_decls {
75+ for ( opaque_type_key, concrete_type) in opaque_ty_decls {
7676 let substs = opaque_type_key. substs ;
7777 debug ! ( ?concrete_type, ?substs) ;
7878
@@ -143,7 +143,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
143143 let ty = infcx. infer_opaque_definition_from_instantiation (
144144 opaque_type_key,
145145 universal_concrete_type,
146- origin,
147146 ) ;
148147 // Sometimes two opaque types are the same only after we remap the generic parameters
149148 // back to the opaque type definition. E.g. we may have `OpaqueType<X, Y>` mapped to `(X, Y)`
@@ -215,7 +214,6 @@ pub trait InferCtxtExt<'tcx> {
215214 & self ,
216215 opaque_type_key : OpaqueTypeKey < ' tcx > ,
217216 instantiated_ty : OpaqueHiddenType < ' tcx > ,
218- origin : OpaqueTyOrigin ,
219217 ) -> Ty < ' tcx > ;
220218}
221219
@@ -248,109 +246,115 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
248246 & self ,
249247 opaque_type_key : OpaqueTypeKey < ' tcx > ,
250248 instantiated_ty : OpaqueHiddenType < ' tcx > ,
251- origin : OpaqueTyOrigin ,
252249 ) -> Ty < ' tcx > {
253250 if let Some ( e) = self . tainted_by_errors ( ) {
254251 return self . tcx . ty_error ( e) ;
255252 }
256253
254+ if let Err ( guar) =
255+ check_opaque_type_parameter_valid ( self . tcx , opaque_type_key, instantiated_ty. span )
256+ {
257+ return self . tcx . ty_error ( guar) ;
258+ }
259+
257260 let definition_ty = instantiated_ty
258261 . remap_generic_params_to_declaration_params ( opaque_type_key, self . tcx , false )
259262 . ty ;
260263
261- if let Err ( guar) = check_opaque_type_parameter_valid (
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 (
262267 self . tcx ,
263- opaque_type_key ,
264- origin ,
268+ self . next_trait_solver ( ) ,
269+ opaque_type_key . def_id ,
265270 instantiated_ty. span ,
271+ definition_ty,
266272 ) {
267- return self . tcx . ty_error ( guar) ;
273+ Ok ( hidden_ty) => hidden_ty,
274+ Err ( guar) => self . tcx . ty_error ( guar) ,
268275 }
276+ }
277+ }
269278
270- // Only check this for TAIT. RPIT already supports `tests/ui/impl-trait/nested-return-type2.rs`
271- // on stable and we'd break that.
272- let OpaqueTyOrigin :: TyAlias { .. } = origin else {
273- return definition_ty;
274- } ;
275- let def_id = opaque_type_key. def_id ;
276- // This logic duplicates most of `check_opaque_meets_bounds`.
277- // FIXME(oli-obk): Also do region checks here and then consider removing `check_opaque_meets_bounds` entirely.
278- let param_env = self . tcx . param_env ( def_id) ;
279- // HACK This bubble is required for this tests to pass:
280- // nested-return-type2-tait2.rs
281- // nested-return-type2-tait3.rs
282- // FIXME(-Ztrait-solver=next): We probably should use `DefiningAnchor::Error`
283- // and prepopulate this `InferCtxt` with known opaque values, rather than
284- // using the `Bind` anchor here. For now it's fine.
285- let infcx = self
286- . tcx
287- . infer_ctxt ( )
288- . with_opaque_type_inference ( if self . next_trait_solver ( ) {
289- DefiningAnchor :: Bind ( def_id)
290- } else {
291- DefiningAnchor :: Bubble
292- } )
293- . build ( ) ;
294- let ocx = ObligationCtxt :: new ( & infcx) ;
295- // Require the hidden type to be well-formed with only the generics of the opaque type.
296- // Defining use functions may have more bounds than the opaque type, which is ok, as long as the
297- // hidden type is well formed even without those bounds.
298- let predicate = ty:: Binder :: dummy ( ty:: PredicateKind :: WellFormed ( definition_ty. into ( ) ) ) ;
299-
300- let id_substs = InternalSubsts :: identity_for_item ( self . tcx , def_id) ;
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) ;
301313
302- // Require that the hidden type actually fulfills all the bounds of the opaque type, even without
303- // the bounds that the function supplies.
304- let opaque_ty = self . tcx . mk_opaque ( def_id. to_def_id ( ) , id_substs) ;
305- if let Err ( err) = ocx. eq (
306- & ObligationCause :: misc ( instantiated_ty. span , def_id) ,
307- param_env,
308- opaque_ty,
309- definition_ty,
310- ) {
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| {
311319 infcx
312320 . err_ctxt ( )
313321 . report_mismatched_types (
314- & ObligationCause :: misc ( instantiated_ty . span , def_id) ,
322+ & ObligationCause :: misc ( definition_span , def_id) ,
315323 opaque_ty,
316324 definition_ty,
317325 err,
318326 )
319- . emit ( ) ;
320- }
327+ . emit ( )
328+ } ) ? ;
321329
322- ocx. register_obligation ( Obligation :: misc (
323- infcx. tcx ,
324- instantiated_ty. span ,
325- def_id,
326- param_env,
327- predicate,
328- ) ) ;
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) ) ;
329335
330- // Check that all obligations are satisfied by the implementation's
331- // version.
332- 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 ( ) ;
333339
334- // This is still required for many(half of the tests in ui/type-alias-impl-trait)
335- // tests to pass
336- 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 ( ) ;
337343
338- if errors. is_empty ( ) {
339- definition_ty
340- } else {
341- let reported = infcx. err_ctxt ( ) . report_fulfillment_errors ( & errors) ;
342- self . tcx . ty_error ( reported)
343- }
344+ if errors. is_empty ( ) {
345+ Ok ( definition_ty)
346+ } else {
347+ Err ( infcx. err_ctxt ( ) . report_fulfillment_errors ( & errors) )
344348 }
345349}
346350
347351fn check_opaque_type_parameter_valid (
348352 tcx : TyCtxt < ' _ > ,
349353 opaque_type_key : OpaqueTypeKey < ' _ > ,
350- origin : OpaqueTyOrigin ,
351354 span : Span ,
352355) -> Result < ( ) , ErrorGuaranteed > {
353- match origin {
356+ let opaque_ty_hir = tcx. hir ( ) . expect_item ( opaque_type_key. def_id ) ;
357+ match opaque_ty_hir. expect_opaque_ty ( ) . origin {
354358 // No need to check return position impl trait (RPIT)
355359 // because for type and const parameters they are correct
356360 // by construction: we convert
0 commit comments