Binders don't switch levels; you don't automatically get an implementation for the higher-ranked type (dyn for<'a> Obj<&'a str>
) even if you have an implementation that covers the same set of types in a non-higher-ranked fashion (every dyn Obj<T>
). You can see this with something like:
trait Ex {}
impl<R> Ex for dyn HandlerObject<R> {}
impl Ex for dyn for<'a> HandlerObject<&'a str> {}
The implementations are allowed to coexist, even though one of the types is a subtype of the other. [1] To paraphrase Ariel,
dyn for<'a> HandlerObject<&'a str>
is not equal todyn HandlerObject<R>
for anyR
(after all, what would thatR
be?for<'a> &'a str
? That is not a type, and would give usdyn HandlerObject<for<'a> &'a str>
, which has thefor
in the wrong place).
(Now, the example does come with a scary warning pointing to issue 56105 and saying it will become a hard error. But to the best of my knowledge, that's a bald-faced lie; the current direction is to continue accepting them. [2])
Your situation is a little different in that you're trying to induce some sort of equality as a type parameter, versus as an implementer, but I believe it comes down to the same distinction.
The more typical example is
fn(T)
vsfn(&T)
-- akafor<'any> fn(&'any T)
. ↩︎Here's another thread with probably way more discussion about it than you care to read; I'm mostly putting a link in here in case I need the breadcrumbs. ↩︎