fix(generic_const_exprs): Fix predicate inheritance for children of opaque types
This commit is contained in:
parent
95a3a7277b
commit
744fa610eb
@ -427,6 +427,8 @@ pub(super) fn explicit_predicates_of<'tcx>(
|
|||||||
} else {
|
} else {
|
||||||
if matches!(def_kind, DefKind::AnonConst) && tcx.lazy_normalization() {
|
if matches!(def_kind, DefKind::AnonConst) && tcx.lazy_normalization() {
|
||||||
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
|
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
|
||||||
|
let parent_def_id = tcx.hir().get_parent_item(hir_id);
|
||||||
|
|
||||||
if tcx.hir().opt_const_param_default_param_hir_id(hir_id).is_some() {
|
if tcx.hir().opt_const_param_default_param_hir_id(hir_id).is_some() {
|
||||||
// In `generics_of` we set the generics' parent to be our parent's parent which means that
|
// In `generics_of` we set the generics' parent to be our parent's parent which means that
|
||||||
// we lose out on the predicates of our actual parent if we dont return those predicates here.
|
// 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>(
|
|||||||
// parent of generics returned by `generics_of`
|
// parent of generics returned by `generics_of`
|
||||||
//
|
//
|
||||||
// In the above code we want the anon const to have predicates in its param env for `T: Trait`
|
// In the above code we want the anon const to have predicates in its param env for `T: Trait`
|
||||||
let item_def_id = tcx.hir().get_parent_item(hir_id);
|
// and we would be calling `explicit_predicates_of(Foo)` here
|
||||||
// In the above code example we would be calling `explicit_predicates_of(Foo)` here
|
return tcx.explicit_predicates_of(parent_def_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
let parent_def_kind = tcx.def_kind(parent_def_id);
|
||||||
|
if matches!(parent_def_kind, DefKind::OpaqueTy) {
|
||||||
|
// In `instantiate_identity` we inherit the predicates of our parent.
|
||||||
|
// However, opaque types do not have a parent (see `gather_explicit_predicates_of`), which means
|
||||||
|
// that we lose out on the predicates of our actual parent if we dont return those predicates here.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// fn foo<T: Trait>() -> impl Iterator<Output = Another<{ <T as Trait>::ASSOC }> > { todo!() }
|
||||||
|
// ^^^^^^^^^^^^^^^^^^^ the def id we are calling
|
||||||
|
// explicit_predicates_of on
|
||||||
|
//
|
||||||
|
// In the above code we want the anon const to have predicates in its param env for `T: Trait`.
|
||||||
|
// However, the anon const cannot inherit predicates from its parent since it's opaque.
|
||||||
|
//
|
||||||
|
// To fix this, we call `explicit_predicates_of` directly on `foo`, the parent's parent.
|
||||||
|
|
||||||
|
// In the above example this is `foo::{opaque#0}` or `impl Iterator`
|
||||||
|
let parent_hir_id = tcx.hir().local_def_id_to_hir_id(parent_def_id.def_id);
|
||||||
|
|
||||||
|
// In the above example this is the function `foo`
|
||||||
|
let item_def_id = tcx.hir().get_parent_item(parent_hir_id);
|
||||||
|
|
||||||
|
// In the above code example we would be calling `explicit_predicates_of(foo)` here
|
||||||
return tcx.explicit_predicates_of(item_def_id);
|
return tcx.explicit_predicates_of(item_def_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,33 @@
|
|||||||
|
// check-pass
|
||||||
|
#![crate_type = "lib"]
|
||||||
|
#![feature(generic_const_exprs)]
|
||||||
|
#![allow(incomplete_features)]
|
||||||
|
pub trait MyIterator {
|
||||||
|
type Output;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Foo {
|
||||||
|
const ABC: usize;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct IteratorStruct<const N: usize>{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Bar<const N: usize> {
|
||||||
|
pub data: [usize; N]
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<const N: usize> MyIterator for IteratorStruct<N> {
|
||||||
|
type Output = Bar<N>;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn test1<T: Foo>() -> impl MyIterator<Output = Bar<{T::ABC}>> where [(); T::ABC]: Sized {
|
||||||
|
IteratorStruct::<{T::ABC}>{}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Baz<const N: usize>{}
|
||||||
|
impl<const N: usize> Baz<N> for Bar<N> {}
|
||||||
|
pub fn test2<T: Foo>() -> impl MyIterator<Output = impl Baz<{ T::ABC }>> where [(); T::ABC]: Sized {
|
||||||
|
IteratorStruct::<{T::ABC}>{}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user