Skip to content

New anonymous class definition will be duplicated at each inline site #22951

Open
@goshacodes

Description

@goshacodes

Compiler version

3.3.5

Minimized code

trait JsonWriter[T] {
   def writeValues(value: T, out: TokenWriter): Unit
}

object JsonWriter:
  inline def derived[T]: JsonWriter[T] = new JsonWriter[T]:
    def writeValues(value: T, out: TokenWriter): Unit = () // here should be some macro code
}

Output

Warning

New anonymous class definition will be duplicated at each inline site

Expectation

No warning. Disabling warning in all project may cause that I miss correct warnings

Why I expect no warning?

  1. Because for different types generated body may vary for performance reasons. (Not full example, just to explain)
case class Foo(foo: String)

new JsonWriter[Foo]:
  def writeValues(value: Foo, out: TokenWriter): Unit =
    tokenWriter.writeFieldName("foo")
    tokenWriter.writeString(value.foo)
  
case class Bar(bar: Int)

new JsonWriter[Bar]:
  def writeValues(value: Bar, out: TokenWriter): Unit =
    tokenWriter.writeFieldName("bar")
    tokenWriter.writeint(value.bar)
  1. Creating class now allows to pass some compile time configuration to derivation
sealed trait WriterBuilder[A]:
  def rename[B](field: A => B)(rename: String): WriterBuilder[A]
  def fieldStyle(style: FieldStyle): WriterBuilder[A]

object WriterBuilder:
  @scala.annotation.compileTimeOnly(
    "Should be declared as inline given or provided directly to derives"
  )
  def apply[A](using
      mirror: scala.deriving.Mirror.ProductOf[A]
  ): WriterBuilder[A] =
    throw IllegalStateException(
      "Config must be an inlined given or provided directly to 'derived'"
    )

Usage is:

given JsonWriter[Foo] = JsonWriter.derived {
  WriterBuilder[Foo].rename(_.foo)("baz") 
}

// and now it should generate

new JsonWriter[Foo]:
  def writeValues(value: Foo, out: TokenWriter): Unit =
    tokenWriter.writeFieldName("baz")
    tokenWriter.writeString(value.foo)
  

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions