-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow to implement abstract inline methods for type classes in quotes #22516
Comments
Macros have some known limitations originating from their design. Making this work should be treated as a new feature in the language rather than a bug fix, even though I'm not sure if this would be doable at all (or with a justifiable cost). import scala.quoted.*
trait TokenWriter
trait JsonWriter[A]:
def write(value: A, tokenWriter: TokenWriter): Unit
object JsonWriter:
inline def derived[A]: JsonWriter[A] = ${ derivedMacro[A] }
def derivedMacro[A : Type](using quotes: Quotes): Expr[JsonWriter[A]] =
val compileTimeConfig: String = "Value from compile time" // fetch compile-time configuration instead
val configExpr = Expr(compileTimeConfig)
'{
new JsonWriter[A]:
def write(value: A, tokenWriter: TokenWriter): Unit =
val config: String = ${configExpr}
println(s"Using config: $config")
// Serialize A here using config
} |
Thank you. My goal is to add an inline to that method since it will really improve runtime performance. So I definitely not want to remove an inline. If my case were simple enough, I would do it without quotes, but I can't. This is the actual code: |
Some high-level description of what you need to optimize would still be useful, so that I could advise something. summon[JsonWriter[A]].write(...) you should do something like writeJson[A](...) with |
We thought about solution without type classes, but we want it to be configurable using type classes as it is now Consider following models: case class Foo(x: Int, bar: String) derives JsonWriter
case class Baz(y: Boolean, foo: Foo) derives JsonWriter Now for new JsonObjectWriter[Baz]:
def write(baz: Baz, out: TokenWriter): Unit =
out.writeObjectStart()
out.writeFieldName("y")
summon[JsonWriter[Boolean].write(baz.y, out) // which calls out.writeBoolean(baz.y)
out.writeFieldName("foo")
summon[JsonWriter[Foo]].write(baz.foo, out) // which calls some methods on out
out.writeObjectEnd() I want it to generate: new JsonObjectWriter[Baz]:
def write(baz: Baz, out: TokenWriter): Unit =
out.writeObjectStart()
out.writeFieldName("y")
out.writeBoolean(baz.y)
out.writeFieldName("foo")
out.writeObjectStart()
out.writeFieldName("x")
out.writeNumber(baz.foo.x)
out.writeFieldName("bar")
out.writeString(baz.foo.bar)
out.writeObjectEnd()
out.writeObjectEnd() Or even just: out.writeObjectStart()
out.writeFieldName("y")
out.writeBoolean(baz.y)
out.writeFieldName("foo")
out.writeObjectStart()
out.writeFieldName("x")
out.writeNumber(baz.foo.x)
out.writeFieldName("bar")
out.writeString(baz.foo.bar)
out.writeObjectEnd()
out.writeObjectEnd() Where final inlined method is this one: extension[A] (a: A)
def writeJson(out: TokenWriter)(using jsonWriter: JsonWriter[A]): Unit =
jsonWriter.write(a, tokenWriter) So expansion should depend on type class instance method implementation |
Hi! I want to implement abstract inline method in macro and it fails. The only way I can derive this is via quotation (there are some compile time configuration, which properly can be used only in macro), so it would be really great to allow this.
Compiler version
3.3.5 and 3.6.3
Minimized code
Output
Expectation
Compiles
The text was updated successfully, but these errors were encountered: