I'm attempting to use existential types in the definition of a trait implementation's associated type. I've minimized what I'm trying to do to the following example:
#![feature(type_alias_impl_trait)]
#![feature(impl_trait_in_assoc_type)]
use std::marker::PhantomData;
trait A<T> {
type Id;
fn check(&self) -> bool;
}
trait B {
}
struct Test<S: A<T>, T: B> {
s: S,
phantom: PhantomData<T>,
}
trait C {
type State;
fn bar(id: &Self::State, a: Self, b: Self) -> Self;
}
struct X();
mod existential {
use super::*;
pub type T = impl B;
pub type S = impl A<T>;
}
impl C for X {
type State = Test<existential::S, existential::T>;
fn bar(id: &Self::State, a: Self, b: Self) -> Self {
if id.s.check() {
a
} else {
b
}
}
}
This fails with:
error: unconstrained opaque type
--> src/lib.rs:30:16
|
30 | pub type T = impl B;
| ^^^^^^
|
= note: `T` must be used in combination with a concrete type within the same module
error: unconstrained opaque type
--> src/lib.rs:31:16
|
31 | pub type S = impl A<T>;
| ^^^^^^^^^
|
= note: `S` must be used in combination with a concrete type within the same module
Is it currently possible to use existential types in this way?