score:7
It turns out that a very natural intent to generate a secondary constructor in a macro annotation has exposed two different issues.
1) The first issue (https://issues.scala-lang.org/browse/SI-8451) is about quasiquotes emitting wrong tree shapes for secondary constructors. That was fixed in 2.11.0-RC4 (yet to be released, currently available as 2.11.0-SNAPSHOT) and in paradise 2.0.0-M6 for 2.10.x (released yesterday).
2) The second issue is about unassigned positions wreaking havoc during typechecker. Curiously enough, when typechecking calls to constructors, typer uses positions in order to decide whether these calls are legal or not. That can't be patched that easily, and we have to work around:
val newCtor = q"""def this() = this(List(Some("")))"""
- val newBody = body :+ newCtor
+
+ // It looks like typer sometimes uses positions to decide whether stuff
+ // (secondary constructors in this case) typechecks or not (?!!):
+ // https://github.com/xeno-by/scala/blob/c74e1325ff1514b1042c959b0b268b3c6bf8d349/src/compiler/scala/tools/nsc/typechecker/Typers.scala#L2932
+ //
+ // In general, positions are important in getting error messages and debug
+ // information right, but maintaining positions is too hard, so macro writers typically don't care.
+ //
+ // This has never been a problem up until now, but here we're forced to work around
+ // by manually setting an artificial position for the secondary constructor to be greater
+ // than the position that the default constructor is going to get after macro expansion.
+ //
+ // We have a few ideas how to fix positions in a principled way in Palladium,
+ // but we'll have to see how it goes.
+ val defaultCtorPos = c.enclosingPosition
+ val newCtorPos = defaultCtorPos.withEnd(defaultCtorPos.endOrPoint + 1).withStart(defaultCtorPos.startOrPoint + 1).withPoint(defaultCtorPos. point + 1)
+ val newBody = body :+ atPos(newCtorPos)(newCtor)
Source: stackoverflow.com
Related Query
- How do I add a no-arg constructor to a Scala case class with a macro annotation?
- How can I apply a macro annotation to a case class with a context bound?
- How to get Scala case class fields and values as (String, String) with Shapeless or Macro
- Scala macro annotation - case class with type parameters
- How to update a mongo record using Rogue with MongoCaseClassField when case class contains a scala Enumeration
- How to create a Scala class with private field with public getter, and primary constructor taking a parameter of the same name
- Does extending a class in scala with constructor params add vals (fields) to the class?
- Scala spark: how to use dataset for a case class with the schema has snake_case?
- Scala (Play 2.4.x) How to call a class with @inject() annotation
- How can I create an instance of a Case Class with constructor arguments with no Parameters in Scala?
- Scala case class copy constructor with dynamic fields
- How to implement a trait with a generic case class that creates a dataset in Scala
- How do I write a scala extractor for a case class with default parameters?
- how to extend (or proxy) a scala class with private constructor
- how to create scala case class with struct types?
- How to create a scala case class instance with a Map instance
- How to serialise a Scala case class with Avro?
- How to partially apply case class with type parameter in Scala
- Get field names from Scala case class with specific annotation
- scala call constructor of case class with all fields except one automatically
- Scala case class constructor with WrappedArray argument
- How to "reads" into a Scala Case Class given a Json object with key names that start with a capital letter
- How to Decode a Generic Case Class with semiautomatic in Circe in Scala 3
- How to flatten a case class with a list value to another case class properly with scala
- Avro to Scala case class annotation with nested types
- How can I use Json.reads to deserialize JSON into a case class with optional constructor parameters
- Scala - How to create a class with a constructor that receives an object as parameter
- Case object extending class with constructor in Scala
- How to override case class field with annotation addition?
- How to Map with a case class in Scala
More Query from same tag
- How to load RDDs from S3 files from spark-shell?
- Parsing an XML Element to Dataframe in scala
- Incorrect path to JAVA_HOME
- Handling same variable in traits
- How to sum adjacent elements in scala
- Call multiple webservices from play 2
- Configuring TheHive with TLS
- Exception in thread "main" java.lang.NoSuchMethodError: scala.Predef$.refArrayOps([Ljava/lang/Object;)Lscala/collection/mutable/ArrayOps
- Create or extend a companion object, using a macro annotation on the class
- Scala List with abstract class type and accessing to child
- How to handle json payload in GET request Play 2.0 + Scala
- Implicit conversions and null
- How to read different lines from a text file simultaneously
- Where does Array get its toList method
- Why does inspect compile:packageWar::packagedArtifact fail in the Sbt console when using xsbt-web-plugin?
- Order by value in spark pair RDD
- scala - map.get returns None for null key but not for null value
- Scala Array map returns ArraySeq
- Workflow and Scheduling Framework for Spark with Scala in Maven Done with Intellij IDEA
- What does `<<=` mean in SBT?
- Preferred way to create a Scala list
- Is there any benefit using index or foreignKey in slick table schema?
- Databricks error java.lang.NoSuchMethodError: scala.Predef$.refArrayOps([Ljava/lang/Object;)[Ljava/lang/Object;
- Message 'No configuration setting found for key' Akka-Http
- Function Pattern matching: Scala - lost in initial call
- Calculate row wise proportions by column name in spark scala
- Scala Slick: Type Mismatch "String vs Tables.Row" during insert
- Http Client timeout when using DataFrame returned from Hive query
- How to force Typesafe Activator to listen 0.0.0.0:8888
- Syntax error at or near "order" (Scala with Quill, Doobie and PostgreSQL)