Is there any workaround for Scala bug SI-7914 - re

2019-05-10 16:35发布

问题:

In our library we have a macro defined like so:

def extractNamed[A]: Any = macro NamedExtractSyntax.extractNamedImpl[A]

This macro uses its type signature to return an apply method whose arguments match the apply method of the case class on which it is typed.

The idea is that this allows the user of our library to make use of Scala's named parameters like so:

lazy val fruitExtractor = extractNamed[Fruit](
  name = FruitTable.name,
  juiciness = FruitTable.juiciness
)

However, this doesn't seem to work - it instead returns error: Any does not take parameters at compile-time.

It seems like this is caused by SI-7914 because it does work if the user explicitly calls apply, i.e.:

lazy val fruitExtractor = extractNamed[Fruit].apply(
  name = FruitTable.name,
  juiciness = FruitTable.juiciness
)

We can work around this by simply renaming the returned method to something sensible, but is there any other way to work around this without requiring an explicit method call?

回答1:

How about returning an subclass of Dynamic from a macro? Then you could define applyDynamic and applyDynamicNamed to do what you want. For additional compile-time safety, you can have those xxxDynamic methods be macros as well. I just checked and this works exactly with the syntax that you want to have.