Skip to content

QuoteContext show can show code that does not compile  #8585

Closed
@valencik

Description

@valencik

The following code is based of the dotty-staging.g8 project.

import scala.quoted._
import scala.quoted.staging.{run, withQuoteContext, Toolbox}

object Main {
  given Toolbox = Toolbox.make(getClass.getClassLoader)

  def main(args: Array[String]): Unit = {
    val toTheEighth = stagedPower(8)
    println("3^8 = " + toTheEighth(3))
  }

  def stagedPower(n: Int): Double => Double = {
    def code(using QuoteContext) = '{ (x: Double) => ${ powerCode(n, 'x) } }
    println("The following would not compile:")
    println(withQuoteContext(code.show))
    run(code)
  }

  def powerCode(n: Int, x: Expr[Double])(using ctx: QuoteContext): Expr[Double] =
    if (n == 1) x
    else if (n == 2) '{ $x * $x }
    else if (n % 2 == 1)  '{ $x * ${ powerCode(n - 1, x) } }
    else '{ val y = $x * $x; ${ powerCode(n / 2, 'y) } }
}

It has been slightly trimmed and modified such that powerCode recursively calls itself twice.
This results in generating two lines starting val y: scala.Double =.

Output

Running this yields the following output:

The following would not compile:
((x: scala.Double) => {
  val y: scala.Double = x.*(x)
  val y: scala.Double = y.*(y)
  y.*(y)
})
3^8 = 6561.0

Attempting to compile that source code yields an error:

[error] 4 |  val y: scala.Double = y.*(y)
[error]   |  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[error]   |  y is already defined as value y

Expectation

code.show should produce a source code representation that compiles.
We can, however, see that the staging works and we get our answer 3^8 = 6561

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions