Help understanding extension trait for &Self and &mut Self references and Sized

The main problem comes from upcasting the potentially existent dyn SubParser into a dyn Parser. Although this should be possible, it is currently not the case in Rust, since there are some unresolved issues about the precise mechanism to achieve this, see this thread and this other one.

This does indeed resolve the upcasting issue, since it adds an explicit method on the vtable in charge of performing the upcasting. It is annoying because it forces you to write the trivial implementation every time you want to implement the trait.

My poor phrasing is to blame, here; the argument is required to be a &mut dyn Parser, which does indeed use dynamic dispatch based on a very precise vtable: dyn Parser's vtable (i.e., dyn SubParser's vtable does not do the trick here).

Now, dyn Parser implements Parser and so does dyn SubParser too. Meaning that both these types could be Self in your example, provided there is not a Self : Sized bound.

  • My &mut impl Parser + ?Sized (i.e., <P : Parser + ?Sized> ... &mut P) solution on the called function allowed to solve the issue since then such function would be able to momonorphise (statically dispatch) to both the P = dyn Parser and P = dyn SubParser cases.

  • And yes, it is true that having to add ?Sized for each generic is annoying :frowning: it's a retrocompatibility artifact from Sized's current design not having existed at the beginning of Rust...

And when Self = dyn SubParser, &mut Self cannot be coerced to a &mut dyn Parser, since that would imply upcasting, which is not a conversion available in Rust directly; hence the requirement for a method such as as_parser_mut.


I hope it's clearer, now :slight_smile:

1 Like