scala3
scala3 copied to clipboard
private inline methods can't call abstract inline methods
Compiler version
3.3.1 (and all current RCs as far as I can tell)
Minimized code
trait SomeTrait:
inline def base: Unit
inline def doSomething: Unit = doSomethingHelper
private inline def doSomethingHelper: Unit = base
object Impl extends SomeTrait:
inline def base: Unit = ()
object Main:
Impl.doSomething
Output
[error] -- Error: /tmp/test/src/main/scala/Main.scala:11:7 -----------------------------
[error] 11 | Impl.doSomething
[error] | ^^^^^^^^^^^^^^^^
[error] | Deferred inline method base in trait SomeTrait cannot be invoked
Expectation
Should compile
Shallow Investigation
I didn't look into this deeply, but maybe the problem has to do with how the support for calling private inline methods is currently handled (see #15075). It works by remapping Select
trees if they are private inline methods:
case tree @ Select(qual: This, name) if tree.symbol.is(Private) && tree.symbol.isInlineMethod =>
// ...
cpy.Select(tree)(qual.asInstance(qual.tpe.widen), name)
which basically rewrites the code
inline def doSomething: Unit = doSomethingHelper
to
inline def doSomething: Unit = this.asInstanceOf[SomeTrait].doSomethingHelper
and I assume this leads the Inliner to select the abstract definition in SomeTrait
later on, not the one on Impl
. Of course, abstract inline methods can't be invoked directly, so when the compiler reaches private def inlineIfNeeded
in Inliner.scala, both the Deferred
and Inline
flags are set and the above error is given.