I wanted to ask for clarification for the return value declaration of methods with this.type
:
Does it guarantee “return value .getClass
will be identical to this.getClass
, and dear compiler, please use the same static type as for the input” or does it guarantee "return value will be the identical JVM object to this
"?
Example that works:
trait MaybeCopy{
def maybeCopy:this.type
}
trait Other{
def foo:Int
}
final class Impl extends MaybeCopy with Other{
def foo:Int = 1
def maybeCopy:this.type = (new Impl).asInstanceOf[this.type]
}
val x: Other with MaybeCopy = new Impl
x.maybeCopy.foo
Example that does not work:
final class Impl extends MaybeCopy with Other{
def foo:Int = 1
def maybeCopy:this.type = (new Impl)
}
cmd11.sc:3: type mismatch;
found : ammonite.$sess.cmd11.Impl
required: Impl.this.type
def maybeCopy:this.type = (new Impl)
^
Compilation Failed
So either scalac is overly cautious at type inference (note that the class was final – Impl
can always be safely upcasted to whatever static type the user had attached to this
) or I am misusing this.type
and optimizations could break my code (would it be legal for the scala compiler to discard the return value of x.maybeCopy
and reuse x
for the second call)?