I have an application that works fine with dyn so far, but I need to convert it to generic, so I created a minimal verifiable example of the problem. I would really appreciate your help.
Basically this represents a read-only cache that can later be flushed into the database (parent). The problem I'm facing now is that the current
View (without generic) cannot be
Send + Sync because the database layer underneath (the database transaction, specifically) cannot be
Send + Sync because it's unnecessary and generally databases don't support that.
But now I have another parent that needs this to be
Send + Sync when it's not using the database as parent.
So, to solve this problem, the only solution I found is to change
ViewCow<'a, P>, where the
dyn View becomes
?Sized. In this model, I'm hoping that whether P is
Send + Sync can be identified through P.
However, this isn't working as expected. As you see in the minimal verifiable example with generics (that doesn't compile). I'm arriving to a circular problem, where if I defined something as
?Sized, the match clause breaks. If I remove it, trait bounds are broken.
Can you please help me in getting this to compile?
TL;DR: this compiles.
The long story Part One is that you can't coerce a
?Sized to a
dyn Trait, because unsized coercion requires "fattening" the pointer (storing the vtable pointer next to the data pointer), but that's impossible if you already have a fat pointer (since currently every fat pointer is made of exactly 2 pointers).
The Long Story Part Two is that for this reason, you should basically get rid of all the
?Sized bounds in most circumstances. So I removed all of those, expecting to use
Box<dyn View> wherever required, by adding a forwarding
impl View for Box<dyn View>. But then I wondered why the compiler complains that
dyn View is unsized.
Turns out, in the
ViewCow::Owned variant, you already stored a
Box<P>. That's pretty much non-idiomatic and unnecessary, and it was in fact why the compiler complained. So I removed that as well, and now
ViewCow::Owned only contains a
P and not a
As a side note, you might also want to
impl<P: View> View for &P and for
&mut P as well.
Thank you very much for your response. I learned a lot from it.
I forgot a detail that there's a
derive_child in the
View which requires
?Sized. But since forgetting to mention that is totally my fault, I'll resolve this question and ask it again with that detail after a few attempts to get rid of it since it seems to be complicating things for no good reason.
Thanks again. Have a great day/evening. Cheers!