Skip to content

Commit 214d6b6

Browse files
authored
Rollup merge of #99801 - Neo-Zhixing:fix/generic_const_exprs_parent_opaque_predicates, r=oli-obk
fix(generic_const_exprs): Fix predicate inheritance for children of opaque types Fixes #99705 We currently have a special case to perform predicate inheritance when the const item is in the generics. I think we're also going to need this for opaque return types. When evaluating the predicates applied to the associated item, it'll inherit from its parent, the opaque type, which will never have predicates applied. This PR bypass the opaque typed parent and inherit predicates directly from the function itself.
2 parents edf0182 + 744fa61 commit 214d6b6

File tree

2 files changed

+62
-2
lines changed

2 files changed

+62
-2
lines changed

compiler/rustc_hir_analysis/src/collect/predicates_of.rs

+29-2
Original file line numberDiff line numberDiff line change
@@ -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
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// check-pass
2+
#![crate_type = "lib"]
3+
#![feature(generic_const_exprs)]
4+
#![allow(incomplete_features)]
5+
pub trait MyIterator {
6+
type Output;
7+
}
8+
9+
pub trait Foo {
10+
const ABC: usize;
11+
}
12+
13+
pub struct IteratorStruct<const N: usize>{
14+
15+
}
16+
17+
pub struct Bar<const N: usize> {
18+
pub data: [usize; N]
19+
}
20+
21+
impl<const N: usize> MyIterator for IteratorStruct<N> {
22+
type Output = Bar<N>;
23+
}
24+
25+
pub fn test1<T: Foo>() -> impl MyIterator<Output = Bar<{T::ABC}>> where [(); T::ABC]: Sized {
26+
IteratorStruct::<{T::ABC}>{}
27+
}
28+
29+
pub trait Baz<const N: usize>{}
30+
impl<const N: usize> Baz<N> for Bar<N> {}
31+
pub fn test2<T: Foo>() -> impl MyIterator<Output = impl Baz<{ T::ABC }>> where [(); T::ABC]: Sized {
32+
IteratorStruct::<{T::ABC}>{}
33+
}

0 commit comments

Comments
 (0)