dotty-feature-requests
dotty-feature-requests copied to clipboard
Infer `this` prefix to extension methods called within a template of a matching type
After recently merged extension methods pull request it still remain issue with accessing to extension methods which apples to this
.
It is naturally expected behavior that this.extensionMethod()
should be also available as simply extensionMethod()
(without this.
prefix) at least in case when extensionMethod
name does not clash with other names available in scope.
So that one may expect that this.extensionMethod()
<==> extensionMethod()
in cases when this.extensionMethod()
is valid/available.
Demonstrating examples:
object TestMainV0 {
def main(args: Array[String]): Unit = {
extensionTargetTest()
}
trait ExtensionTarget
def (`this`: ExtensionTarget) testedExtensionMethod (): String = "hardcode"
object extensionTargetTest extends ExtensionTarget {
def apply() : Unit = {
assert("hardcode" == this.testedExtensionMethod()) // this line works as expected
assert(this.testedExtensionMethod() == testedExtensionMethod()) // <-- this line cause compilation error
}
}
}
Compilation fails with error
assert(this.testedExtensionMethod() == testedExtensionMethod()) // <-- this line cause compilation error
^^^^^^^^^^^^^^^^^^^^^^^
missing argument for parameter this of method testedExtensionMethod: (this: M04_02_v0.ExtensionTarget)(): String
object TestMainV1 {
def main(args: Array[String]): Unit = {
extensionTargetTest()
}
trait ExtensionTarget
implicit object extensionProvider {
def (`this`: ExtensionTarget) testedExtensionMethod (): String = "hardcode"
}
object extensionTargetTest extends ExtensionTarget {
def apply() : Unit = {
assert("hardcode" == this.testedExtensionMethod()) // this line works as expected
assert(this.testedExtensionMethod() == testedExtensionMethod()) // <-- this line cause compilation error
}
}
}
object TestMainV2 {
def main(args: Array[String]): Unit = {
extensionTargetTest()
}
trait ExtensionTarget
trait ExtensionProvider {
def (`this`: ExtensionTarget) testedExtensionMethod (): String = "hardcode"
}
object extensionTargetTest extends ExtensionTarget {
def apply() : Unit = {
implicit object extensionProvider extends ExtensionProvider
assert("hardcode" == this.testedExtensionMethod()) // this line works as expected
assert(this.testedExtensionMethod() == testedExtensionMethod()) // <-- this line cause compilation error
}
}
}
Compilation fails with error
assert(this.testedExtensionMethod() == testedExtensionMethod()) // <-- this line cause compilation error
^^^^^^^^^^^^^^^^^^^^^
not found: testedExtensionMethod
FYI
In Kotlin extension methods applied to this
could be called without this.
prefix (so that it works as expected in Kotlin)
similar kotlin snippet: (compiles and runs as is)
object TestsMain {
@JvmStatic
fun main(args: Array<String>) {
extensionTargetTest()
}
fun ExtensionTarget2.testedExtensionMethod(): String = "hardcode"
interface ExtensionTarget2
object extensionTargetTest : ExtensionTarget2 {
operator fun invoke() : Unit {
assert("hardcode" == this.testedExtensionMethod())
assert(this.testedExtensionMethod() == testedExtensionMethod())
}
}
}
Bigger motivational example in this post