@@ -427,6 +427,8 @@ pub(super) fn explicit_predicates_of<'tcx>(
427
427
} else {
428
428
if matches ! ( def_kind, DefKind :: AnonConst ) && tcx. lazy_normalization ( ) {
429
429
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
+
430
432
if tcx. hir ( ) . opt_const_param_default_param_hir_id ( hir_id) . is_some ( ) {
431
433
// In `generics_of` we set the generics' parent to be our parent's parent which means that
432
434
// 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>(
439
441
// parent of generics returned by `generics_of`
440
442
//
441
443
// 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
444
471
return tcx. explicit_predicates_of ( item_def_id) ;
445
472
}
446
473
}
0 commit comments