I wonder what is the reasoning behind the following behaviour?
@ trait Bar
defined trait Bar
@ trait Foo { self: Bar => }
defined trait Foo
@ def x: Foo = ???
defined function x
@ val y: Bar = x
cmd3.sc:1: type mismatch;
found : ammonite.$sess.cmd1.Foo
required: ammonite.$sess.cmd0.Bar
val y: Bar = x
^
Compilation Failed
AFAIU, Foo
requires each of its subtypes to be a subtype of Bar
so why instance of Foo
is not a proper instance of Bar
?
@Edit
Just to make the question clearer: I wonder why it works like that. Some possible answers are:
- There is feature X that would not be possible with subtyping relation between those.
- It's not true that the subtyping relation occurs (e.g. exists such instance of type
Foo
which is not the instance of typeBar
in runtime) - Both scenarios (with and without subtyping relation) are valid and so the compiler team had to choose one of them. If so, was there a reason to make such a decision or it was a random choice?
It seems that at least 1) is somewhat true (hiding subtyping as implementation detail).
Because a selftype is an implementation detail of the
Foo
trait. You may want to implementFoo
's methods in terms of methods that you inherit fromBar
, but not expose that fact to the users of your API.