I don’t have a strong opinion about #[sealed]
itself, but I’m very interested in the stated motivation. #[sealed]
is essentially a more nuanced kind of privacy for traits (you can see it but you can’t implement it). My intuition is that privacy toggles are not the correct solution to coherence issues, but the motivation is a coherence issue.
In particular, it sounds like the reason #[sealed]
would solve your problem here is the implicit negative reasoning in local contexts codified by RFC 1023, but the inferred mutual exclusion allowed in local contexts is probably a mistake.
The first example works because there is an inferred (A, B): !FromSql<(A, B)>
. My understanding is that the second does not work because it will not allow the inference that (A, B): !FromSql<T(A, B), DB>
because of the additional parameter. (Note: if my understanding is correct, there is a mistake in the RFC that the child crate is said to be able to implement FromSqlRow
, not FromSql
. Let me know if instead I am mistaken.) But if you could just explicitly impl<A, B, DB> !FromSql<(A, B), DB> for (A, B)
, the problem would be solved, no?
I think that’s what you actually want here. The motivation for sealing traits has to do with finer grained privacy and performance optimizations in trait objects, not with coherence.
FWIW, my experience working through this example is exactly why I said that 1023 inferred mutual exclusion is a misfeature. Working out what exclusions it will allow and what it won’t is mindbogglingly hard.