@@ -31,6 +31,7 @@ use rustc_target::abi::FieldIdx;
31
31
use rustc_target:: spec:: abi:: Abi ;
32
32
use rustc_trait_selection:: traits:: error_reporting:: on_unimplemented:: OnUnimplementedDirective ;
33
33
use rustc_trait_selection:: traits:: error_reporting:: TypeErrCtxtExt as _;
34
+ use rustc_trait_selection:: traits:: outlives_bounds:: InferCtxtExt as _;
34
35
use rustc_trait_selection:: traits:: { self , ObligationCtxt , TraitEngine , TraitEngineExt as _} ;
35
36
36
37
use std:: ops:: ControlFlow ;
@@ -222,7 +223,7 @@ fn check_opaque(tcx: TyCtxt<'_>, id: hir::ItemId) {
222
223
if check_opaque_for_cycles ( tcx, item. owner_id . def_id , substs, span, & origin) . is_err ( ) {
223
224
return ;
224
225
}
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) ;
226
227
}
227
228
228
229
/// 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>(
391
392
fn check_opaque_meets_bounds < ' tcx > (
392
393
tcx : TyCtxt < ' tcx > ,
393
394
def_id : LocalDefId ,
394
- substs : SubstsRef < ' tcx > ,
395
395
span : Span ,
396
396
origin : & hir:: OpaqueTyOrigin ,
397
397
) {
@@ -406,6 +406,8 @@ fn check_opaque_meets_bounds<'tcx>(
406
406
. with_opaque_type_inference ( DefiningAnchor :: Bind ( defining_use_anchor) )
407
407
. build ( ) ;
408
408
let ocx = ObligationCtxt :: new ( & infcx) ;
409
+
410
+ let substs = InternalSubsts :: identity_for_item ( tcx, def_id. to_def_id ( ) ) ;
409
411
let opaque_ty = tcx. mk_opaque ( def_id. to_def_id ( ) , substs) ;
410
412
411
413
// `ReErased` regions appear in the "parent_substs" of closures/generators.
@@ -448,9 +450,18 @@ fn check_opaque_meets_bounds<'tcx>(
448
450
match origin {
449
451
// Checked when type checking the function containing them.
450
452
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 => { }
451
460
// Can have different predicates to their defining use
452
461
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) ;
454
465
let _ = ocx. resolve_regions_and_report_errors ( defining_use_anchor, & outlives_env) ;
455
466
}
456
467
}
0 commit comments