It appears to make a difference whether you refer to this.type
from inside a Trait or from the scope where the object is created, with surprising results.
import scala.reflect.runtime.universe._
trait Trait {
val ttag = typeOf[this.type]
println(s"Trait constructor: $this")
}
object Instance1 extends Trait
object Instance2 extends Trait
println(typeOf[Instance1.type] =:= typeOf[Instance2.type]) // Should be false
println(Instance1.ttag =:= Instance2.ttag) // Should be false
println(Instance1.ttag =:= typeOf[Instance1.type]) // Should be true
Here's the output:
false // As expected: the singleton types of two objects are different.
Trait constructor: $line9.$read$$iw$$iw$$iw$$iw$Instance1$@58c46295
Trait constructor: $line10.$read$$iw$$iw$$iw$$iw$Instance2$@452451ba
true // But the this.type tags are equivalent
false // and the this.type tag is not equivalent to the singleton type.
So, there are two distinct objects, but apparently each is getting an equivalent type tag for its this.type
, which is not equivalent to the .type
of the object as seen from an enclosing scope.
Is this a compiler bug, or, if not, could you explain why this behavior makes sense?
(I'm running Scala 2.11.2. I've tried it with a self
alias for this
, with the same result.)
Trait
,this.type
has prefixTrait
, resulting in typeTrait.this.type
—for all instances.Instance1.type
has a prefix saying that the object is defined in the top-level scope, with nameInstance1
, resulting in typeInstance1.type
—different than insideTrait
. – Milord