@@ -31,6 +31,7 @@ use rustc_target::abi::FieldIdx;
3131use rustc_target:: spec:: abi:: Abi ;
3232use rustc_trait_selection:: traits:: error_reporting:: on_unimplemented:: OnUnimplementedDirective ;
3333use rustc_trait_selection:: traits:: error_reporting:: TypeErrCtxtExt as _;
34+ use rustc_trait_selection:: traits:: outlives_bounds:: InferCtxtExt as _;
3435use rustc_trait_selection:: traits:: { self , ObligationCtxt , TraitEngine , TraitEngineExt as _} ;
3536
3637use std:: ops:: ControlFlow ;
@@ -222,7 +223,7 @@ fn check_opaque(tcx: TyCtxt<'_>, id: hir::ItemId) {
222223 if check_opaque_for_cycles ( tcx, item. owner_id . def_id , substs, span, & origin) . is_err ( ) {
223224 return ;
224225 }
225- check_opaque_meets_bounds ( tcx, item. owner_id . def_id , substs , span, & origin) ;
226+ check_opaque_meets_bounds ( tcx, item. owner_id . def_id , span, & origin) ;
226227}
227228
228229/// Checks that an opaque type does not use `Self` or `T::Foo` projections that would result
@@ -391,7 +392,6 @@ pub(super) fn check_opaque_for_cycles<'tcx>(
391392fn check_opaque_meets_bounds < ' tcx > (
392393 tcx : TyCtxt < ' tcx > ,
393394 def_id : LocalDefId ,
394- substs : SubstsRef < ' tcx > ,
395395 span : Span ,
396396 origin : & hir:: OpaqueTyOrigin ,
397397) {
@@ -406,6 +406,8 @@ fn check_opaque_meets_bounds<'tcx>(
406406 . with_opaque_type_inference ( DefiningAnchor :: Bind ( defining_use_anchor) )
407407 . build ( ) ;
408408 let ocx = ObligationCtxt :: new ( & infcx) ;
409+
410+ let substs = InternalSubsts :: identity_for_item ( tcx, def_id. to_def_id ( ) ) ;
409411 let opaque_ty = tcx. mk_opaque ( def_id. to_def_id ( ) , substs) ;
410412
411413 // `ReErased` regions appear in the "parent_substs" of closures/generators.
@@ -448,9 +450,18 @@ fn check_opaque_meets_bounds<'tcx>(
448450 match origin {
449451 // Checked when type checking the function containing them.
450452 hir:: OpaqueTyOrigin :: FnReturn ( ..) | hir:: OpaqueTyOrigin :: AsyncFn ( ..) => { }
453+ // Nested opaque types occur only in associated types:
454+ // ` type Opaque<T> = impl Trait<&'static T, AssocTy = impl Nested>; `
455+ // They can only be referenced as `<Opaque<T> as Trait<&'static T>>::AssocTy`.
456+ // We don't have to check them here because their well-formedness follows from the WF of
457+ // the projection input types in the defining- and use-sites.
458+ hir:: OpaqueTyOrigin :: TyAlias
459+ if tcx. def_kind ( tcx. parent ( def_id. to_def_id ( ) ) ) == DefKind :: OpaqueTy => { }
451460 // Can have different predicates to their defining use
452461 hir:: OpaqueTyOrigin :: TyAlias => {
453- let outlives_env = OutlivesEnvironment :: new ( param_env) ;
462+ let wf_tys = ocx. assumed_wf_types ( param_env, span, def_id) ;
463+ let implied_bounds = infcx. implied_bounds_tys ( param_env, def_id, wf_tys) ;
464+ let outlives_env = OutlivesEnvironment :: with_bounds ( param_env, implied_bounds) ;
454465 let _ = ocx. resolve_regions_and_report_errors ( defining_use_anchor, & outlives_env) ;
455466 }
456467 }
0 commit comments