Closed
Description
Minimized code
package x
import scala.quoted._
trait CB[T]:
def map[S](f: T=>S): CB[S] = ???
def flatMap[S](f: T=>CB[S]): CB[S] = ???
class MyArr[AK,AV]:
def map1[BK,BV](f: ((AK,AV)) => (BK, BV)):MyArr[BK,BV] = ???
def map1Out[BK, BV](f: ((AK,AV)) => CB[(BK,BV)]): CB[MyArr[BK,BV]] = ???
def await[T](x:CB[T]):T = ???
object CBM:
def pure[T](t:T):CB[T] = ???
object X:
inline def process[T](inline f:T) = ${
processImpl[T]('f)
}
def processImpl[T:Type](f:Expr[T])(using qctx: QuoteContext):Expr[CB[T]] =
import qctx.reflect._
def transform(term:Term):Term =
term match
case Apply(TypeApply(Select(obj,"map1"),targs),args) =>
val nArgs = args.map(x => shiftLambda(x))
val nSelect = Select.unique(obj, "map1Out")
Apply(TypeApply(nSelect,targs),nArgs)
case Apply(TypeApply(Ident("await"),targs),args) => args.head
case a@Apply(x,List(y,z)) =>
val mty=MethodType(List("y1"))( _ => List(y.tpe.widen), _ => Type[CB].unseal.tpe.appliedTo(a.tpe.widen))
val mtz=MethodType(List("z1"))( _ => List(z.tpe.widen), _ => a.tpe.widen)
Apply(
TypeApply(Select.unique(transform(y),"flatMap"),
List(Inferred(a.tpe.widen))
),
List(
Lambda(mty, yArgs =>
Apply(
TypeApply(Select.unique(transform(z),"map"),
List(Inferred(a.tpe.widen))
),
List(
Lambda(mtz, zArgs => {
val termYArgs = yArgs.asInstanceOf[List[Term]]
val termZArgs = zArgs.asInstanceOf[List[Term]]
Apply(x,List(termYArgs.head,termZArgs.head))
})
)
)
)
)
)
case Block(stats, last) => Block(stats, transform(last))
case Inlined(x,List(),body) => transform(body)
case l@Literal(x) =>
l.seal match
case '{ $l: $L } =>
'{ CBM.pure(${term.seal.cast[L]}) }.unseal
case other =>
throw RuntimeException(s"Not supported $other")
def shiftLambda(term:Term): Term =
term match
case lt@Lambda(params, body) =>
val paramTypes = params.map(_.tpt.tpe)
val paramNames = params.map(_.name)
val mt = MethodType(paramNames)(_ => paramTypes, _ => Type[CB].unseal.tpe.appliedTo(body.tpe.widen) )
Lambda(mt, args => changeArgs(params,args,transform(body)) )
case Block(stats, last) =>
Block(stats, shiftLambda(last))
case _ =>
throw RuntimeException("lambda expected")
def changeArgs(oldArgs:List[Tree], newArgs:List[Tree], body:Term):Term =
val association: Map[Symbol, Term] = (oldArgs zip newArgs).foldLeft(Map.empty){
case (m, (oldParam, newParam: Term)) => m.updated(oldParam.symbol, newParam)
case (m, (oldParam, newParam: Tree)) => throw RuntimeException("Term expected")
}
val changes = new TreeMap() {
override def transformTerm(tree:Term)(using Context): Term =
tree match
case ident@Ident(name) => association.getOrElse(ident.symbol, super.transformTerm(tree))
case _ => super.transformTerm(tree)
}
changes.transformTerm(body)
val r = transform(f.unseal).seal.cast[CB[T]]
//println(s"r=${r.show}")
r
and class Main:
package x
object Main {
def main(args:Array[String]):Unit =
val arr = new MyArr[Int,Int]()
val r = X.process{
arr.map1( (x,y) =>
( 1, await(CBM.pure(x)) )
)
}
println("r")
}
Output (click arrow to expand)
[info] exception occurred while compiling /Users/rssh/tests/dotty/crash-compiler2/src/main/scala/x/Main.scala
java.lang.IllegalArgumentException: Could not find proxy for x$1: Tuple2/T in List(val x$1, method $anonfun, val r, method main, module class Main$, module class x, module class <root>), encl = method $anonfun, owners = method $anonfun, value r, method main, object Main/T, package x/T, package <root>/T; enclosures = method $anonfun, package x/T, package <root>/T while compiling /Users/rssh/tests/dotty/crash-compiler2/src/main/scala/x/Main.scala
[error] ## Exception when compiling 2 sources to /Users/rssh/tests/dotty/crash-compiler2/target/scala-3.0.0-M2/classes
[error] java.lang.IllegalArgumentException: Could not find proxy for x$1: Tuple2/T in List(val x$1, method $anonfun, val r, method main, module class Main$, module class x, module class <root>), encl = method $anonfun, owners = method $anonfun, value r, method main, object Main/T, package x/T, package <root>/T; enclosures = method $anonfun, package x/T, package <root>/T
[error] dotty.tools.dotc.transform.LambdaLift$Lifter.searchIn$1(LambdaLift.scala:395)
[error] dotty.tools.dotc.transform.LambdaLift$Lifter.proxy(LambdaLift.scala:408)
[error] dotty.tools.dotc.transform.LambdaLift$Lifter.proxyRef(LambdaLift.scala:426)
[error] dotty.tools.dotc.transform.LambdaLift$Lifter.addFreeArgs$$anonfun$1(LambdaLift.scala:432)
[error] scala.collection.immutable.List.map(List.scala:246)
[error] dotty.tools.dotc.transform.LambdaLift$Lifter.addFreeArgs(LambdaLift.scala:432)
[error] dotty.tools.dotc.transform.LambdaLift.transformApply(LambdaLift.scala:553)
[error] dotty.tools.dotc.transform.LambdaLift.transformApply(LambdaLift.scala:552)
[error] dotty.tools.dotc.transform.MegaPhase.goApply(MegaPhase.scala:644)
[error] dotty.tools.dotc.transform.MegaPhase.transformUnnamed$1(MegaPhase.scala:281)
[error] dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:429)
[error] dotty.tools.dotc.transform.MegaPhase.recur$2(MegaPhase.scala:453)
[error] dotty.tools.dotc.transform.MegaPhase.transformTrees(MegaPhase.scala:453)
[error] dotty.tools.dotc.transform.MegaPhase.transformUnnamed$1(MegaPhase.scala:280)
[error] dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:429)
[error] dotty.tools.dotc.transform.MegaPhase.recur$2(MegaPhase.scala:453)
[error] dotty.tools.dotc.transform.MegaPhase.transformTrees(MegaPhase.scala:453)
[error] dotty.tools.dotc.transform.MegaPhase.transformUnnamed$1(MegaPhase.scala:280)
[error] dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:429)
[error] dotty.tools.dotc.transform.MegaPhase.transformNamed$1(MegaPhase.scala:228)
[error] dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:427)
[error] dotty.tools.dotc.transform.MegaPhase.transformUnnamed$1(MegaPhase.scala:279)
[error] dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:429)
[error] dotty.tools.dotc.transform.MegaPhase.mapDefDef$1(MegaPhase.scala:249)
[error] dotty.tools.dotc.transform.MegaPhase.transformNamed$1(MegaPhase.scala:252)
[error] dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:427)
[error] dotty.tools.dotc.transform.MegaPhase.transformStat$2(MegaPhase.scala:437)
[error] dotty.tools.dotc.transform.MegaPhase.recur$1(MegaPhase.scala:442)
[error] dotty.tools.dotc.transform.MegaPhase.transformStats(MegaPhase.scala:442)
[error] dotty.tools.dotc.transform.MegaPhase.transformUnnamed$1(MegaPhase.scala:299)
[error] dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:429)
[error] dotty.tools.dotc.transform.MegaPhase.recur$2(MegaPhase.scala:453)
[error] dotty.tools.dotc.transform.MegaPhase.transformTrees(MegaPhase.scala:453)
[error] dotty.tools.dotc.transform.MegaPhase.transformUnnamed$1(MegaPhase.scala:280)
[error] dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:429)
[error] dotty.tools.dotc.transform.MegaPhase.transformUnnamed$1(MegaPhase.scala:300)
[error] dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:429)
[error] dotty.tools.dotc.transform.MegaPhase.mapDefDef$1(MegaPhase.scala:249)
[error] dotty.tools.dotc.transform.MegaPhase.transformNamed$1(MegaPhase.scala:252)
[error] dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:427)
[error] dotty.tools.dotc.transform.MegaPhase.transformStat$2(MegaPhase.scala:437)
[error] dotty.tools.dotc.transform.MegaPhase.recur$1(MegaPhase.scala:442)
[error] dotty.tools.dotc.transform.MegaPhase.transformStats(MegaPhase.scala:442)
[error] dotty.tools.dotc.transform.MegaPhase.transformUnnamed$1(MegaPhase.scala:299)
[error] dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:429)
[error] dotty.tools.dotc.transform.MegaPhase.recur$2(MegaPhase.scala:453)
[error] dotty.tools.dotc.transform.MegaPhase.transformTrees(MegaPhase.scala:453)
[error] dotty.tools.dotc.transform.MegaPhase.transformUnnamed$1(MegaPhase.scala:280)
[error] dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:429)
[error] dotty.tools.dotc.transform.MegaPhase.transformUnnamed$1(MegaPhase.scala:323)
[error] dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:429)
[error] dotty.tools.dotc.transform.MegaPhase.mapValDef$1(MegaPhase.scala:235)
[error] dotty.tools.dotc.transform.MegaPhase.transformNamed$1(MegaPhase.scala:240)
[error] dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:427)
[error] dotty.tools.dotc.transform.MegaPhase.transformStat$2(MegaPhase.scala:437)
[error] dotty.tools.dotc.transform.MegaPhase.recur$1(MegaPhase.scala:442)
[error] dotty.tools.dotc.transform.MegaPhase.recur$1(MegaPhase.scala:1061)
[error] dotty.tools.dotc.transform.MegaPhase.transformStats(MegaPhase.scala:442)
[error] dotty.tools.dotc.transform.MegaPhase.transformUnnamed$1(MegaPhase.scala:299)
[error] dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:429)
[error] dotty.tools.dotc.transform.MegaPhase.mapDefDef$1(MegaPhase.scala:249)
[error] dotty.tools.dotc.transform.MegaPhase.transformNamed$1(MegaPhase.scala:252)
[error] dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:427)
[error] dotty.tools.dotc.transform.MegaPhase.transformStat$2(MegaPhase.scala:437)
[error] dotty.tools.dotc.transform.MegaPhase.recur$1(MegaPhase.scala:442)
[error] dotty.tools.dotc.transform.MegaPhase.recur$1(MegaPhase.scala:1061)
[error] dotty.tools.dotc.transform.MegaPhase.transformStats(MegaPhase.scala:442)
[error] dotty.tools.dotc.transform.MegaPhase.transformUnnamed$1(MegaPhase.scala:362)
[error] dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:429)
[error] dotty.tools.dotc.transform.MegaPhase.transformNamed$1(MegaPhase.scala:256)
[error] dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:427)
[error] dotty.tools.dotc.transform.MegaPhase.transformStat$2(MegaPhase.scala:437)
[error] dotty.tools.dotc.transform.MegaPhase.recur$1(MegaPhase.scala:442)
[error] dotty.tools.dotc.transform.MegaPhase.recur$1(MegaPhase.scala:1061)
[error] dotty.tools.dotc.transform.MegaPhase.transformStats(MegaPhase.scala:442)
[error] dotty.tools.dotc.transform.MegaPhase.mapPackage$1(MegaPhase.scala:382)
[error] dotty.tools.dotc.transform.MegaPhase.transformUnnamed$1(MegaPhase.scala:385)
[error] dotty.tools.dotc.transform.MegaPhase.transformTree(MegaPhase.scala:429)
[error] dotty.tools.dotc.transform.MegaPhase.transformUnit(MegaPhase.scala:448)
[error] dotty.tools.dotc.transform.MegaPhase.run(MegaPhase.scala:460)
[error] dotty.tools.dotc.core.Phases$Phase.runOn$$anonfun$1(Phases.scala:296)
[error] scala.collection.immutable.List.map(List.scala:246)
[error] dotty.tools.dotc.core.Phases$Phase.runOn(Phases.scala:297)
[error] dotty.tools.dotc.Run.runPhases$4$$anonfun$4(Run.scala:185)
[error] dotty.runtime.function.JProcedure1.apply(JProcedure1.java:15)
[error] dotty.runtime.function.JProcedure1.apply(JProcedure1.java:10)
[error] scala.collection.ArrayOps$.foreach$extension(ArrayOps.scala:1323)
[error] dotty.tools.dotc.Run.runPhases$5(Run.scala:195)
[error] dotty.tools.dotc.Run.compileUnits$$anonfun$1(Run.scala:203)
[error] dotty.runtime.function.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:12)
[error] dotty.tools.dotc.util.Stats$.maybeMonitored(Stats.scala:67)
[error] dotty.tools.dotc.Run.compileUnits(Run.scala:210)
[error] dotty.tools.dotc.Run.compileSources(Run.scala:147)
[error] dotty.tools.dotc.Run.compile(Run.scala:129)
[error] dotty.tools.dotc.Driver.doCompile(Driver.scala:38)
[error] dotty.tools.dotc.Driver.process(Driver.scala:194)
[error] dotty.tools.dotc.Main.process(Main.scala)
[error] xsbt.CachedCompilerImpl.run(CachedCompilerImpl.java:69)
[error] xsbt.CompilerInterface.run(CompilerInterface.java:41)
[error] sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[error] sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
[error] sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[error] java.lang.reflect.Method.invoke(Method.java:498)
[error] sbt.internal.inc.AnalyzingCompiler.invoke(AnalyzingCompiler.scala:330)
[error] sbt.internal.inc.AnalyzingCompiler.compile(AnalyzingCompiler.scala:113)
[error] sbt.internal.inc.MixedAnalyzi