Skip to content

Staging: Substituting values for mutable variables generates invalid code #9692

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
b-studios opened this issue Sep 1, 2020 · 0 comments · Fixed by #9696
Closed

Staging: Substituting values for mutable variables generates invalid code #9692

b-studios opened this issue Sep 1, 2020 · 0 comments · Fixed by #9696

Comments

@b-studios
Copy link
Contributor

When using the staging API one can extract a mutable variable into a HOAS function and then substitute a value. This will generate an assignment to the substituted value, which is clearly wrong.

Minimized code

import scala.quoted._
import scala.quoted.staging._

object Test extends App {

  // make available the necessary toolbox for runtime code generation
  given Toolbox = Toolbox.make(getClass.getClassLoader)

  run {
    val expr: Expr[Int] = '{ var x = 1; x = 2; 42 }

    expr match {
      case '{ var x: Int = $binding; $body(x): Int } =>
    val res = Expr.betaReduce('{ $body(4) })
    println(res.show)
    res
      case _ => println(expr.show); '{0}
    }
  }
}

Output (click arrow to expand)

[warn] -- Warning: /Users/jonathan/playground/staging-test/src/main/scala/Main.scala:14:4
[warn] 14 |    val res = Expr.betaReduce('{ $body(4) })
[warn]    |    ^
[warn]    |    Line is indented too far to the left, or a `}` is missing
[warn] -- Warning: /Users/jonathan/playground/staging-test/src/main/scala/Main.scala:15:4
[warn] 15 |    println(res.show)
[warn]    |    ^
[warn]    |    Line is indented too far to the left, or a `}` is missing
[warn] -- Warning: /Users/jonathan/playground/staging-test/src/main/scala/Main.scala:16:4
[warn] 16 |    res
[warn]    |    ^
[warn]    |    Line is indented too far to the left, or a `}` is missing
[warn] three warnings found
[info] running Test
{
  4 = 2
  42
}
[error] (run-main-3) java.lang.AssertionError: assertion failed: asTerm called on not-a-Term val <none>
[error] java.lang.AssertionError: assertion failed: asTerm called on not-a-Term val <none>
[error] 	at dotty.DottyPredef$.assertFail(DottyPredef.scala:17)
[error] 	at dotty.tools.dotc.core.Symbols$Symbol.asTerm(Symbols.scala:156)
[error] 	at dotty.tools.dotc.transform.Getters.transformAssign(Getters.scala:114)
[error] 	at dotty.tools.dotc.transform.MegaPhase.goAssign(MegaPhase.scala:718)
[error] 	at dotty.tools.dotc.transform.MegaPhase.transformUnnamed$1(MegaPhase.scala:344)
[error] 	at dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:428)
[error] 	at dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:424)
[error] 	at dotty.tools.dotc.transform.MegaPhase.transformStat$2(MegaPhase.scala:438)
[error] 	at dotty.tools.dotc.transform.MegaPhase.recur$1(MegaPhase.scala:441)
[error] 	at dotty.tools.dotc.transform.MegaPhase.transformStats(MegaPhase.scala:441)
[error] 	at dotty.tools.dotc.transform.MegaPhase.transformUnnamed$1(MegaPhase.scala:298)
[error] 	at dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:428)
[error] 	at dotty.tools.dotc.transform.MegaPhase.mapDefDef$1(MegaPhase.scala:248)
[error] 	at dotty.tools.dotc.transform.MegaPhase.transformNamed$1(MegaPhase.scala:251)
[error] 	at dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:426)
[error] 	at dotty.tools.dotc.transform.MegaPhase.transformStat$2(MegaPhase.scala:436)
[error] 	at dotty.tools.dotc.transform.MegaPhase.recur$1(MegaPhase.scala:441)
[error] 	at dotty.tools.dotc.transform.MegaPhase.transformStats(MegaPhase.scala:441)
[error] 	at dotty.tools.dotc.transform.MegaPhase.transformUnnamed$1(MegaPhase.scala:361)
[error] 	at dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:428)
[error] 	at dotty.tools.dotc.transform.MegaPhase.transformNamed$1(MegaPhase.scala:255)
[error] 	at dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:426)
[error] 	at dotty.tools.dotc.transform.MegaPhase.transformStat$2(MegaPhase.scala:436)
[error] 	at dotty.tools.dotc.transform.MegaPhase.recur$1(MegaPhase.scala:441)
[error] 	at dotty.tools.dotc.transform.MegaPhase.transformStats(MegaPhase.scala:441)
[error] 	at dotty.tools.dotc.transform.MegaPhase.mapPackage$1(MegaPhase.scala:381)
[error] 	at dotty.tools.dotc.transform.MegaPhase.transformUnnamed$1(MegaPhase.scala:384)
[error] 	at dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:428)
[error] 	at dotty.tools.dotc.transform.MegaPhase.transformUnit(MegaPhase.scala:447)
[error] 	at dotty.tools.dotc.transform.MegaPhase.run(MegaPhase.scala:459)
[error] 	at dotty.tools.dotc.core.Phases$Phase.runOn$$anonfun$1(Phases.scala:296)
[error] 	at scala.collection.immutable.List.map(List.scala:246)
[error] 	at dotty.tools.dotc.core.Phases$Phase.runOn(Phases.scala:297)
[error] 	at dotty.tools.dotc.Run.runPhases$4$$anonfun$4(Run.scala:180)
[error] 	at dotty.runtime.function.JProcedure1.apply(JProcedure1.java:15)
[error] 	at dotty.runtime.function.JProcedure1.apply(JProcedure1.java:10)
[error] 	at scala.collection.ArrayOps$.foreach$extension(ArrayOps.scala:1323)
[error] 	at dotty.tools.dotc.Run.runPhases$5(Run.scala:190)
[error] 	at dotty.tools.dotc.Run.compileUnits$$anonfun$1(Run.scala:198)
[error] 	at dotty.runtime.function.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:12)
[error] 	at dotty.tools.dotc.util.Stats$.maybeMonitored(Stats.scala:64)
[error] 	at dotty.tools.dotc.Run.compileUnits(Run.scala:205)
[error] 	at dotty.tools.dotc.Run.compileUnits(Run.scala:147)
[error] 	at scala.quoted.staging.QuoteCompiler$ExprRun.compileExpr(QuoteCompiler.scala:107)
[error] 	at scala.quoted.staging.QuoteDriver.run(QuoteDriver.scala:39)
[error] 	at scala.quoted.staging.Toolbox$$anon$1.run(Toolbox.scala:36)
[error] 	at scala.quoted.staging.package$.run(staging.scala:19)
[error] 	at Test$.<clinit>(Main.scala:19)
[error] 	at Test.main(Main.scala)
[error] 	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[error] 	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
[error] 	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[error] 	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants