8000 When a `case class` has a companion object with at least a single `val` inside `Transformer` optimizations for nested transformations don't kick in · Issue #41 · arainko/ducktape · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
When a case class has a companion object with at least a single val inside Transformer optimizations for nested transformations don't kick in #41
Closed
@arainko

Description

@arainko

Let's say we have a set of case classes and we summon a Transformer for the topelevel ones:

final case class Id(value: String, in: Inside)
final case class Inside(str: String)

final case class Id2(value: String)
final case class Inside2(str: String, in: Inside2)

// exactly what one would expect, no nested transformers are created and the transformation for `Inside2` is 'inlined'
// (inline$make$i1[Id, Id2](ForProduct)((((source: Id) => new Id2(value = source.value, in = new Inside2(str = source.in.str))): Transformer[Id, Id2])): ForProduct[Id, Id2])
Transformer.Debug.showCode(summon[Transformer[Id, Id2]])

now let's tweak the definitions a tiny bit:

final case class Id(value: String, in: Inside)

final case class Inside(str: String)
object Inside {
  val a = 1
}

final case class Id2(value: String, in: Inside2)
final case class Inside2(str: String)
Transformer.Debug.showCode(summon[Transformer[Id, Id2]])
/*
(inline$make$i1[Id, Id2](ForProduct)((((source: Id) => new Id2(value = source.value, in = {
  val x$1$proxy2: Product {
    type MirroredMonoType >: Inside <: Inside
    type MirroredType >: Inside <: Inside
    type MirroredLabel >: "Inside" <: "Inside"
    type MirroredElemTypes >: *:[String, EmptyTuple] <: *:[String, EmptyTuple]
    type MirroredElemLabels >: *:["str", EmptyTuple] <: *:["str", EmptyTuple]
  } = Inside.$asInstanceOf$[Product {
    type MirroredMonoType >: Inside <: Inside
    type MirroredType >: Inside <: Inside
    type MirroredLabel >: "Inside" <: "Inside"
    type MirroredElemTypes >: *:[String, EmptyTuple] <: *:[String, EmptyTuple]
    type MirroredElemLabels >: *:["str", EmptyTuple] <: *:["str", EmptyTuple]
  }]

  (inline$make$i1[Inside, Inside2](ForProduct)((((`source₂`: Inside) => new Inside2(str = `source₂`.str)): Transformer[Inside, Inside2])): ForProduct[Inside, Inside2])
}.transform(source.in))): Transformer[Id, Id2])): ForProduct[Id, Id2])
*/

After adding an arbitrary val to Inside's companion Inside's Mirror now appears in the inlined code (even tho it's not spliced into the AST anywhere!) and introduces another Inlined node which throws off LiftedTransformation's optimizations.

The resulting code should get rid of the excessive instance of Transformer.ForProduct for Inside and inline the transformation. The mirror needs to stay there for better or for worse as we can't be sure about it not being used inside the AST (maybe erased definitions will save us here once they land?)

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions

    0