Say that we create a class with an inline member and a macro that prints it during compile-time.
package example
import scala.quoted._
import scala.quoted.matching._
import scala.compiletime._
// Create a class
class DualTestClass {
inline def v = "foo"
inline def compiletimeValue: Unit = ${ DualTestClass.compiletimeValueImpl('v) }
}
// Add a macro that prints an inline paramter
object DualTestClass {
def compiletimeValueImpl(input: Expr[String])(given qctx: QuoteContext): Expr[Unit] = {
val v = input match { case Value(v) => v }
println("*********** Compile-Time Value is: " + v + " *******************")
'{ () }
}
}
// Then create a instance of that class (using a factory-pattern just because...)
object DualTestClassMaker {
def make: DualTestClass =
new DualTestClass {
override inline def v = "bar"
}
}
Then let's run this:
package example
@main def dualTestClassTester() = {
DualTestClassMaker.make.compiletimeValue
}
When the code is compiling, it will print the value:
*********** Compile-Time Value is: foo *******************
As opposed to this which is the expectation.
*********** Compile-Time Value is: bar *******************
Also note that when I properly extend DualTestClass like this:
class DualTestClassExt extends DualTestClass {
override inline def v = "bar"
}
and then run it:
@main def dualTestClassTester() = {
new DualTestClassExt().compiletimeValue
}
Then the correct value is printed:
*********** Compile-Time Value is: bar *******************
It is also interesting to note that if you try to create the subclass DualTestClassExt inside of a macro (I call it DualTestInst) the same error happens.
Here's the macro:
object DualTestClassMaker {
import scala.quoted._
inline def makeMacro: DualTestClass = ${ dualTestImpl }
def dualTestImpl(given qctx: QuoteContext): Expr[DualTestClass] = {
'{
class DualTestInst extends DualTestClass {
override inline def v = "bar"
}
new DualTestInst
}
}
}
Then I run it:
@main def dualTestClassTester() = {
DualTestClassMaker.makeMacro.compiletimeValue
}
It prints out:
*********** Compile-Time Value is: foo *******************
Which is also incorrect.
As far as I can tell, the inline mechanism functions correctly in the examples you gave. You seem to need to take into account that what matters for inline are the _static_ arguments to calls (even more specifically: the _types_ of the static arguments), not the runtime ones.
For instance, in your first example, the static type of the object you call compiletimeValue on is the actual DualTestClass, not the anonymous class that you create inside the body of make. If you made make an inline method, I believe it would work according to your expectations.
If this clears up your doubts, I'll close the issue.
Most helpful comment
As far as I can tell, the
inlinemechanism functions correctly in the examples you gave. You seem to need to take into account that what matters forinlineare the _static_ arguments to calls (even more specifically: the _types_ of the static arguments), not the runtime ones.For instance, in your first example, the static type of the object you call
compiletimeValueon is the actualDualTestClass, not the anonymous class that you create inside the body ofmake. If you mademakeaninlinemethod, I believe it would work according to your expectations.If this clears up your doubts, I'll close the issue.