-
Notifications
You must be signed in to change notification settings - Fork 13.4k
Associated type constraint fails, even if it implements requested trait #76407
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Comments
Also, if |
This variant also fails to compile, but doesn't use GATs: My guess is that this is the same bug. We are missing a normalization somewhere. |
Projections aren't getting normalized because:
|
I could confirm with TryFrom trait associated type Error's Debug constraint, used as generic return type |
#![feature(generic_associated_types)]
trait Monad {
type Unplug;
type Plug<B>: Monad;
fn bind<B, F>(self, f: F) -> Self::Plug<B>
where
F: Fn(Self::Unplug) -> Self::Plug<B>;
}
impl<A> Monad for Option<A> {
type Unplug = A;
type Plug<B> = Option<B>;
fn bind<B, F>(self, f: F) -> Option<B>
where
F: Fn(A) -> Option<B>,
{
self.and_then(f)
}
}
fn stringify<T, M1>(m: M1) -> <M1 as Monad>::Plug<String>
where
T: core::fmt::Display,
M1: Monad<Unplug = T>,
{
m.bind(|x| Some(format!("{}", x)))
} |
@cynecx I don't think your example should compile. #![feature(generic_associated_types)]
trait Monad {
type Unplug;
type Plug<B>: Monad;
fn bind<B, F>(self, f: F) -> Self::Plug<B>
where
F: Fn(Self::Unplug) -> Self::Plug<B>;
}
impl<A> Monad for Option<A> {
type Unplug = A;
type Plug<B> = Option<B>;
fn bind<B, F>(self, f: F) -> Option<B>
where
F: Fn(A) -> Option<B>,
{
self.and_then(f)
}
}
impl<A> Monad for Result<A, ()> {
type Unplug = A;
type Plug<B> = Result<B, ()>;
fn bind<B, F>(self, f: F) -> Result<B, ()>
where
F: Fn(A) -> Result<B, ()>
{
self.and_then(f)
}
}
fn stringify<T, M1>(m: M1) -> <M1 as Monad>::Plug<String>
where
T: core::fmt::Display,
M1: Monad<Unplug = T>,
{
m.bind(|x| Some(format!("{}", x)))
}
fn main() {
let a: Result<i32, ()> = Ok(0);
stringify(a); // In this case <M1 as Monad>::Plug<String> = Result<String, ()>`, not `Option<String>`!
} Edit: the following compiles, this may be what you want: #![feature(generic_associated_types)]
trait Monad {
type Unplug;
type Plug<B>: Monad<Unplug = B>;
fn plug(t: Self::Unplug) -> Self;
fn bind<B, F>(self, f: F) -> Self::Plug<B>
where
F: Fn(Self::Unplug) -> Self::Plug<B>;
}
impl<A> Monad for Option<A> {
type Unplug = A;
type Plug<B> = Option<B>;
fn plug(t: Self::Unplug) -> Self {
Some(t)
}
fn bind<B, F>(self, f: F) -> Option<B>
where
F: Fn(A) -> Option<B>,
{
self.and_then(f)
}
}
fn stringify<T, M1>(m: M1) -> <M1 as Monad>::Plug<String>
where
T: core::fmt::Display,
M1: Monad<Unplug = T>,
{
m.bind(|x| M1::Plug::plug(format!("{}", x)))
} |
@SkiFire13 Oh wow. (...I feel stupid). Thanks for pointing that out :D |
Associated type constraint fails, even if it implements requested trait. In the example below, requested trait is
Marker
,u32
implements it,<MyStruct as MyTrait>::Item<'a> == u32
, but<MyStruct as MyTrait>::Item<'a>: Marker
does not pass. (Everything is ok with<'a>
removed)The code:
Meta
rustc --version --verbose
:The text was updated successfully, but these errors were encountered: