@@ -427,6 +427,8 @@ pub(super) fn explicit_predicates_of<'tcx>(
427427 } else {
428428 if matches ! ( def_kind, DefKind :: AnonConst ) && tcx. lazy_normalization ( ) {
429429 let hir_id = tcx. hir ( ) . local_def_id_to_hir_id ( def_id. expect_local ( ) ) ;
430+ let parent_def_id = tcx. hir ( ) . get_parent_item ( hir_id) ;
431+
430432 if tcx. hir ( ) . opt_const_param_default_param_hir_id ( hir_id) . is_some ( ) {
431433 // In `generics_of` we set the generics' parent to be our parent's parent which means that
432434 // we lose out on the predicates of our actual parent if we dont return those predicates here.
@@ -439,8 +441,33 @@ pub(super) fn explicit_predicates_of<'tcx>(
439441 // parent of generics returned by `generics_of`
440442 //
441443 // In the above code we want the anon const to have predicates in its param env for `T: Trait`
442- let item_def_id = tcx. hir ( ) . get_parent_item ( hir_id) ;
443- // In the above code example we would be calling `explicit_predicates_of(Foo)` here
444+ // and we would be calling `explicit_predicates_of(Foo)` here
445+ return tcx. explicit_predicates_of ( parent_def_id) ;
446+ }
447+
448+ let parent_def_kind = tcx. def_kind ( parent_def_id) ;
449+ if matches ! ( parent_def_kind, DefKind :: OpaqueTy ) {
450+ // In `instantiate_identity` we inherit the predicates of our parent.
451+ // However, opaque types do not have a parent (see `gather_explicit_predicates_of`), which means
452+ // that we lose out on the predicates of our actual parent if we dont return those predicates here.
453+ //
454+ //
455+ // fn foo<T: Trait>() -> impl Iterator<Output = Another<{ <T as Trait>::ASSOC }> > { todo!() }
456+ // ^^^^^^^^^^^^^^^^^^^ the def id we are calling
457+ // explicit_predicates_of on
458+ //
459+ // In the above code we want the anon const to have predicates in its param env for `T: Trait`.
460+ // However, the anon const cannot inherit predicates from its parent since it's opaque.
461+ //
462+ // To fix this, we call `explicit_predicates_of` directly on `foo`, the parent's parent.
463+
464+ // In the above example this is `foo::{opaque#0}` or `impl Iterator`
465+ let parent_hir_id = tcx. hir ( ) . local_def_id_to_hir_id ( parent_def_id. def_id ) ;
466+
467+ // In the above example this is the function `foo`
468+ let item_def_id = tcx. hir ( ) . get_parent_item ( parent_hir_id) ;
469+
470+ // In the above code example we would be calling `explicit_predicates_of(foo)` here
444471 return tcx. explicit_predicates_of ( item_def_id) ;
445472 }
446473 }
0 commit comments