Say I have the following traits:
trait A
trait B { this: A => }
trait C extends B // { this: A => }
Compiler error: illegal inheritance; self-type C does not conform to B's selftype B with A
As expected if I uncomment the self type annotation, the compiler is happy.
I think it's quite obvious why C also needs this self type. What I don't understand why it can not "inherit" it from A if the compiler could already figure out that it's needed?
I think it could reduce the verbosity when you use self types with complicated hierarchies, especially if you mix in a big bunch of traits, each of them having its own self type.
I guess probably there is a good reason for the current behavior, I just could not find/figure out what it is.
At first I thought it might be related to mixin linearization, but it seems to me it does not play here (even if I had more traits mixed in with more complicated self types).
Would it cause ambiguities in some cases? If so, why can't it work when there is no ambiguity?
Or is it related to some difficulties in proper implementation of it?
I could find some discussions about the topic (like self type is not inherited), but they mostly just state the problem and conclude that's how it is without too much explanation and/or a solution (if it exists).
trait C extends B with A
is not the only solution. You could also have
trait AA extends A
trait C extends B with AA
That is, everything that inherits the interface of A
is accepted. If you must rely on a concrete implementation, you would chose a mixin; if the implementation is up to the user or you have a good reason for not specifying the mixin in the trait (for example to loosen dependency issues), you would make it a self-type.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With