-
Notifications
You must be signed in to change notification settings - Fork 12.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Associated type constraint fails, even if it implements requested trait #76407
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: