Help with a bound that should be satisfied


#1

This code works:

trait Tr {}

impl<'a> Tr for &'a u8 {}

trait Test {
    fn f();
}

impl Test for u64
where
    for<'a> &'a u8: Tr
{
    fn f() {}
}

fn main() {
    // confirm that the bound for<'a> &'a u8: Tr is satisfied.
    u64::f()
}

But this doesn’t compile, with the message error[E0599]: no function or associated item named ``f`` found for type ``u64`` in the current scope:

trait Tr {}

impl<'a> Tr for &'a u8 {}

trait Test {
    fn f();
}

trait L<'a> {
    type T;
}

impl<'a> L<'a> for u64 {
    type T = &'a u8;
}

impl Test for u64
where
    for<'a> <u64 as L<'a>>::T: Tr
{
    fn f() {}
}

fn main() {
    // this won't compile, apparently because for<'a> <u64 as L<'a>>::T: Tr is not
    // satisfied.
    u64::f()
}

This is hard to understand because it seems like the types <u64 as L<'a>>::T and &'a u8 are identical. Any suggestions?


#2

I suspect it’s another example of https://github.com/rust-lang/rust/issues/30472


#3

Ah. Thanks.

That’s really unfortunate. It seems that for every language I’ve used with a fancy type system, it’s impossible to actually do any of the fancy stuff without slamming up against the system’s limitations, whether those limitations are by design or are bugs.

I now have so many instances where I want to do something with lifetimes that seems natural to me, but it doesn’t work, and so I have to throw away the lifetime approach and use closures instead.


#4

Yeah, I hear you. This is actually one of my main concerns with Rust at the moment.

In the example code here, switching to L<'a, T> (instead of associated type) seems to work but you’d need to implement Tr for all types that you’d use as a bound on T in L<'a, T>. Needless to say, not great (and may not jive with your real code).


#5

Hmm. I don’t think I can make that work in my code, but I’ll think about it.

Thanks again.