Potential Compiler Bug / Limitation With Trait Used As An Alias

Consider this code here.

This is a reproduction of an issue I have when using serde::de::DeserializeSeed, which in this example I replaced with the trait Hello. Using the bound Wrapper<T>: for<'a> Hello<'a, Value = T> is quite cumbersome, and so I tried to use a "trait alias", i.e. a trait which is implemented for all types with this bound and satisfies this bound (Helloable). As you can see in the example, this doesn't always compile, even though using the bound directly does. Is this a compiler bug? Is it a limitation? Can I work around this in any way other than only using the cumbersome bound directly?

If we remove the where clause in the trait definition it compiles. Since it is redundant with the following impl it seems unnecessary. And since it is your trait, you do not need to add a bound to prevent you from adding new impls.

/// The helper trait
trait Helloable: Sized
//where //<-- removed
    //Wrapper<Self>: for<'a> Hello<'a, Value = Self>,
{
}

impl<T> Helloable for T where Wrapper<T>: for<'a> Hello<'a, Value = T> {}

Can you check if this is enough in your real use case?

Are you talking about issue #20671 or something else?

If that's about #20671, then yes, it's how compiler known to work, if maybe, not how you expect it to work.

Indeed, if you remove wheels from the car then it no longer would be susceptible to traffic jams… but it wouldn't be able to move you anywhere either!

The topicstarter's idea was to use Helloable as “something for which Wrapper with certain properties exist”.

And instead of adding that where clause everywhere just have it in Helloable.

But because of #20671 it doesn't work in quite that way — and your version is even worse: now Helloable is entirely detached from all the where clauses which means that it wouldn't even work later, when/if #20671 would be fixed.

#20671 might be related, but the error is completely different- here the compiler spins into an infinite recursion of tuples, despite the fact that no tuple is even used in the code. I'm pretty sure this is a separate issue, and after running it past a colleague I opened a github issue, since I can't find any reason for this behaviour other than a bug. Even if the compiler can't deduce that there's an implementation for that trait, I see no reason for it to check recursively for every possible nesting of tuples.

The next-gen trait solver gives almost the correct error message. (The suggestion misses the associated type equality bound.)

I was doubting that part was actually needed. Perhaps it is true, then an alternative bound would be to use Wrapper<T>: AnyHello<T> with AnyHello defined by

trait AnyHello<T> : for<'a> Hello<'a, Value = T> {}
impl<T> AnyHello<T> for Wrapper<T>
  where Wrapper<T>: for<'a> Hello<'a, Value = T> {}

which preserves exactly the meaning and I think it is simple enough. See this playground.

Also note that the issue still occurs without that higher ranked lifetime or associated types, as shown in this other playground.

Edit 1: Also relevant the issue #44491.
Edit 2: As another alternative, you may use the unstable trait alias feature.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.