Skip to content

compiler crash when transform call for argument expression, which transform lambda defined as function from tuple inside #10151

Closed
@rssh

Description

@rssh

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions