When generating code that uses matchers to compute types, the code compiles, but running it results in the runtime error:
34 | def reify[A] given Type[A] = m => '{ k => ${ Effects[L].reify[E] { m( a => Effects[L].reflect[E]('k(a))) } }}
| ^
| value apply is not a member of R
| This location is in code that was inlined at Bug.scala:34
Here is the full example code (sorry for not being able to minimize further):
package examples
import scala.quoted._
object bug extends App {
val toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader)
implied for scala.quoted.Toolbox = toolbox
sealed trait HList
sealed trait HNil extends HList
sealed trait ::[E, T <: HList] extends HList
type STM[A, L <: HList] = L match {
case HNil => Expr[A]
case e :: rs => (Expr[A] => STM[e, rs]) => STM[e, rs]
}
type Stm[A, L <: HList] = L match {
case HNil => A
case e :: rs => (A => Stm[e, rs]) => Stm[e, rs]
}
trait Effects[L <: HList] {
def reify[A] given Type[A]: STM[A, L] => Expr[Stm[A, L]]
def reflect[A] given Type[A]: Expr[Stm[A, L]] => STM[A, L]
}
implied empty for Effects[HNil] {
def reify[A] given Type[A] = m => m
def reflect[A] given Type[A] = m => m
}
// for reify, we need type tags for E and also strangely for L.
implied cons [E, L <: HList] given Effects[L] given Type[E] given Type[L] for Effects[E :: L] {
def reify[A] given Type[A] = m => '{ k => ${ Effects[L].reify[E] { m( a => Effects[L].reflect[E]('k(a))) } }}
def reflect[A] given Type[A] = m => k => Effects[L].reflect[E] { m('{ a => ${ Effects[L].reify[E]( k('a)) } })}
}
def Effects[L <: HList] given Effects[L]: Effects[L] = the[Effects[L]]
type RS = Boolean :: RS2
type RS2 = Int :: String :: HNil
val m: STM[Int, RS] = k => k('{42})
// compiles, but results in a runtime error:
// println(Effects[RS].reify[Int] { m }.show)
//
// the implicit search results in the following value:
// val effects = cons[Boolean, RS2] given (cons[Int, String :: HNil] given (cons[String, HNil] given empty))
//
// so the above is equivalent to:
// println(effects.reify[Int] { m }.show)
//
// error:
// 37 | def reify[A] given Type[A] = m => '{ k => ${ Effects[L].reify[E] { m( a => Effects[L].reflect[E]('k(a))) } }}
// | ^
// | value apply is not a member of R
// | This location is in code that was inlined at Bug.scala:37
// manually inlining reify works
// val res : Expr[Stm[Int, RS]] = '{ k => ${ Effects[RS2].reify[Boolean] { m(a => Effects[RS2].reflect[Boolean]('k(a))) }}}
// println(res.show)
}
On the example: Both STM and Stm are matchers that given a list of types (HList) compute a new type. The resulting type is produced by iterating CPS.
From @biboudis minimization I minimized it further to
import scala.quoted._
object Test {
val toolbox = scala.quoted.Toolbox.make(getClass.getClassLoader)
implied for scala.quoted.Toolbox = toolbox
sealed trait HList
sealed trait HNil extends HList
sealed trait ::[E, T <: HList] extends HList
type Stm[A, L <: HList] = L match {
case HNil => A
case e :: rs => (A => Stm[e, rs]) => Stm[e, rs]
}
def main(args: Array[String]): Unit = {
val boom = '{ (x: Int) => (??? : Stm[Int, Int :: Int :: HNil]) }
val foo: Expr[Int] =
'{ println(); ${
boom('{4})('{ (a4: Int) => (k4: Int => Int) => ${ 'k4('a4) } } )('{ (a7: Int) => a7 })
} }
println(foo.show)
}
}
19 | val boom = '{ (x: Int) => (??? : Stm[Int, Int :: Int :: HNil]) }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| value apply is not a member of R
true
Exception in thread "main" java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at dotty.tools.vulpix.ChildJVMMain.runMain(ChildJVMMain.java:40)
at dotty.tools.vulpix.ChildJVMMain.main(ChildJVMMain.java:47)
Caused by: java.lang.Exception: Could not extract Expr(<pickled tasty>)
at dotty.tools.dotc.quoted.QuoteDriver.withTree$$
Great! Thanks for looking at the issue
Even after merging #6322 this issue still occurs, so I guess it was not the reason for it.
@b-studios it looks like it is fixed now. I added the full code that is in the first snippet in #6840 and all seemed to work.
Most helpful comment
From @biboudis minimization I minimized it further to