A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://github.com/playframework/play-json/issues/971 below:

"Exception occurred while executing macro expansion." · Issue #971 · playframework/play-json · GitHub

Play JSON Version (2.5.x / etc)

2.10.4

API (Scala / Java / Neither / Both)

Scala

Operating System (Ubuntu 15.10 / MacOS 10.10 / Windows 10)

MacOS 14.2.1

bwbecker@beta playjson % uname -a
Darwin beta 23.2.0 Darwin Kernel Version 23.2.0: Wed Nov 15 21:53:18 PST 2023; root:xnu-10002.61.3~2/RELEASE_ARM64_T6000 arm64
JDK (Oracle 1.8.0_72, OpenJDK 1.8.x, Azul Zing)
bwbecker@beta playjson % java -version
openjdk version "17.0.9" 2023-10-17
OpenJDK Runtime Environment Homebrew (build 17.0.9+0)
OpenJDK 64-Bit Server VM Homebrew (build 17.0.9+0, mixed mode, sharing)
Library Dependencies

None.

Expected Behavior

I expect to be able to combine a type parameter and a default value in a case class and for Play-Json to be able to automatically derive the appropriate Reads and Writes.

// Version 3 -- Fails with "Exception occurred while executing macro expansion."
case class Data[T](
    data: T,
    descr: String = "Default value"
)

object Data {
  implicit def errorWrites[T](implicit writes:Writes[T]): Writes[Data[T]]     = Json.writes[Data[T]]
  implicit def errorReads[T](implicit reads:Reads[T]): Reads[Data[T]]         = Json.reads[Data[T]]
}

Actual Behavior

The compiler throws the following error:

bwbecker@beta playjson % scala-cli error.scala
Compiling project (Scala 3.3.1, JVM (17))
[error] ./error.scala:58:81
[error] Exception occurred while executing macro expansion.
[error] java.lang.Exception: Expected an expression. This is a partially applied Term. Try eta-expanding the term first.
[error] 	at scala.quoted.runtime.impl.QuotesImpl$reflect$TreeMethods$.asExpr(QuotesImpl.scala:110)
[error] 	at scala.quoted.runtime.impl.QuotesImpl$reflect$TreeMethods$.asExprOf(QuotesImpl.scala:116)
[error] 	at scala.quoted.runtime.impl.QuotesImpl$reflect$TreeMethods$.asExprOf(QuotesImpl.scala:115)
[error] 	at play.api.libs.json.JsMacroImpl$ReadsHelper$$anon$2.applyOrElse(JsMacroImpl.scala:332)
[error] 	at scala.PartialFunction$Lifted.apply(PartialFunction.scala:338)
[error] 	at scala.PartialFunction$Lifted.apply(PartialFunction.scala:334)
[error] 	at scala.Option.collect(Option.scala:462)
...
Reproducible Test Case

Place the following in error.scala and then run it with scala-cli error.scala.

It contains three examples; remove/replace comments as appropriate for each one.

Example 1: Works as expected, demonstrating use of a type variable, T, for data.

Example 2: Works as expected, demonstrating the use of a default value for descr.

Example 3: Combines the two above examples, generating a compile-time exception.

//> using dep     com.typesafe.play::play-json:2.10.4


import play.api.libs.json._
import Data._

object Main {

    def main(args:Array[String]):Unit = {
        println("Hello, world!")

        // Versions 1 and 3
        val err = Data[Int](400, "Some error")
        val jsonString = Json.toJson(err).toString
        println(jsonString)
        val obj = Json.parse(jsonString).validate[Data[Int]].get
        println(obj)

        // Version 2
        // val err = Data(400)
        // val jsonString = Json.toJson(err).toString
        // println(jsonString)
        // val obj = Json.parse(jsonString).validate[Data].get
        // println(obj)

    }
}

// Version 1 -- Works as expected with type parameter
// case class Data[T](
//     data: T,
//     descr: String
// )

// object Data {
//   implicit def errorWrites[T](implicit writes:Writes[T]): Writes[Data[T]]     = Json.writes[Data[T]]
//   implicit def errorReads[T](implicit reads:Reads[T]): Reads[Data[T]]         = Json.reads[Data[T]]
// }

// Version 2 -- Works as expected with default parameter
// case class Data(
//     data: Int,
//     descr: String = "Default value"
// )

// object Data {
//   implicit def errorWrites: Writes[Data]     = Json.writes[Data]
//   implicit def errorReads: Reads[Data]         = Json.reads[Data]
// }

// Version 3 -- Fails with "Exception occurred while executing macro expansion."
case class Data[T](
    data: T,
    descr: String = "Default value"
)

object Data {
  implicit def errorWrites[T](implicit writes:Writes[T]): Writes[Data[T]]     = Json.writes[Data[T]]
  implicit def errorReads[T](implicit reads:Reads[T]): Reads[Data[T]]         = Json.reads[Data[T]]
}

RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4