dotty-feature-requests
dotty-feature-requests copied to clipboard
Allow specifying this to be an inline parameter on inline methods
This request is paraphrased from this issue on Dotty proper, which started as an improvement I was planning on implementing for inliner internals: https://github.com/lampepfl/dotty/issues/8294#issuecomment-585328641. Now it seems we need a new language feature to get the feature I wanted working...
Take this example:
import scala.compiletime._
object Test {
case class B(i: Int)
case class C(b: B) {
inline def giveMeI: Int =
inline b match {
case B(i) => i
}
}
def main(argv: Array[String]): Unit =
println(code"${ C(B(12)).giveMeI }")
}
Even with the improvement mentioned in the issue I reference above, the best we can hope for is this kind of expansion:
{
val C_b: Test.B = B(12)
val B_i: Int = C_b.i
i
}
This is OK as a simple performance-minded elision of the C
instance, but if we actually intended to fully destructure C(B(12))
at compile-time then we reach an impasse where it would be unsound to treat the members of C
as inline because nowhere have they been defined as such.
Really, we need the ability to specify an inline method's this
as inline, like we can for all its other parameters.
Here is a straw-man of this idea:
import scala.compiletime._
object Test {
case class B(i: Int)
case class C(b: B) {
inline[this] def giveMeI: Int =
inline b match {
case B(i) => i
}
}
def main(argv: Array[String]): Unit =
println(code"${ C(B(12)).giveMeI }")
}
inline[this]
tells the inliner that we intend to treat this
as an inline parameter, so we end up with this kind of substitution when expanding giveMeI
:
inline C(B(12)).b match {
case B(i) => i
}
Unlike before, we can fully expect to see C(B(12))
evaluated any number of times (including 0!), so it's fine to just paste it everywhere. Then, the rest of the inliner's rules can (in this case) reduce the expression to the 12
we wanted while completely eliding both nested case class instances.
One thing I have not fully thought through: in my straw man syntax, can you put something other than this
in inline[this]
, similar to private[...]
? Would that make any semantic sense / have any use?