Working through these posts had me thinking I understood self-types, at least somewhat.
So I created an example which failed as expected:
scala> trait A { val v = "a" }
defined trait A
scala> trait B { this :A => ; var v = "" ; this.v = "b" }
<console>:6: error: reassignment to val
trait B { this :A => ; var v = "" ; this.v = "b" }
^
The self-type's "this" shadows B's "this" -- it looks weird, but makes sense.
It would seem wise, then, to give the self-type a different name. I did this and was rather surprised:
scala> trait C { a :A => ; var v = "" ; this.v = "c" }
<console>:6: error: reassignment to val
trait C { a :A => ; var v = "" ; this.v = "c" }
^
It's still shadowed???
Changing the name of the 'local' variable let things compile, which makes sense:
scala> trait D { a :A => ; var w = "" ; this.w = a.v }
defined trait D
(And the self-type name can optionally be used to clarify which "v" to use.)
Okay. Which means that the following should fail?
scala> trait E { this :A => ; var w = "" ; this.w = this.v }
defined trait E
Huh? Which this is this? :-(
So... is there a point to naming self-types? "this" seems to end up shadowed regardless.
Or is this an edge-case of scoping rules, where the self-type's "this" takes precedence over the trait's "this" -- and one should just avoid using the same names for things in related traits?