Skip to content

Quoted n-ary tuple referring to method params crashes during lambdaLift #23313

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

Open
TomasMikula opened this issue Jun 3, 2025 · 0 comments
Open

Comments

@TomasMikula
Copy link
Contributor

Compiler version

3.7.0

Minimized code

macros.scala

import scala.quoted.*

transparent inline def makeAnonFun: (String => Tuple1[String]) =
  ${ makeAnonFunImpl }

// Synthesizes anonymous function
//   (s: String) => s *: EmptyTuple
def makeAnonFunImpl(using Quotes): Expr[String => Tuple1[String]] = {
  import quotes.reflect.*

  val methSym = Symbol.newMethod(
    parent = Symbol.spliceOwner,
    "myMethod",
    MethodType(paramNames = List("s"))(
      mt => List(TypeRepr.of[String]),
      mt => TypeRepr.of[Tuple1[String]]
    )
  )

  val meth = DefDef(
    methSym,
    rhsFn = { case List(args) =>

      // OK: using `Tuple1(...)`
      Some('{ Tuple1(${args(0).asExprOf[String]}) }.asTerm)

      // KO: using `... *: EmptyTuple`
      Some('{ ${args(0).asExprOf[String]} *: EmptyTuple }.asTerm)
    }
  )

  Block(
    List(meth),
    Closure(Ident(methSym.termRef), tpe = None)
  ).asExprOf[String => Tuple1[String]]
}

test.scala

object Test extends App:
  val f = makeAnonFun
  println(f("hi"))

The problem clearly has to do with using the *: syntax, as using Tuple1(...) (or (..., ...) for binary+ tuples) works inside quotes.

Output (click arrow to expand)

error lambda lifting test.scala: value x$1 is not visible from <none>
% scalac macros.scala test.scala
-- [E029] Pattern Match Exhaustivity Warning: macros.scala:22:14 ---------------
22 |    rhsFn = { case List(args) =>
   |              ^
   |              match may not be exhaustive.
   |
   |              It would fail on pattern case: List(_*, _, _*), Nil
   |
   | longer explanation available when compiling with `-explain`
1 warning found
error lambda lifting test.scala: value x$1 is not visible from  <none>

  unhandled exception while running MegaPhase{lambdaLift, elimStaticThis, countOuterAccesses} on test.scala

  An unhandled exception was thrown in the compiler.
  Please file a crash report here:
  https://github.com/scala/scala3/issues/new/choose
  For non-enriched exceptions, compile with -Xno-enrich-error-messages.


     while compiling: test.scala
        during phase: MegaPhase{lambdaLift, elimStaticThis, countOuterAccesses}
                mode: Mode(ImplicitsEnabled)
     library version: version 2.13.16
    compiler version: version 3.7.0
            settings: 


  Exception while compiling macros.scala, test.scala

  An unhandled exception was thrown in the compiler.
  Please file a crash report here:
  https://github.com/scala/scala3/issues/new/choose
  For non-enriched exceptions, compile with -Xno-enrich-error-messages.


     while compiling: <no file>
        during phase: parser
                mode: Mode()
     library version: version 2.13.16
    compiler version: version 3.7.0
            settings: 

Exception in thread "main" dotty.tools.dotc.transform.Dependencies$NoPath
	at dotty.tools.dotc.transform.Dependencies.markFree(Dependencies.scala:137)
	at dotty.tools.dotc.transform.Dependencies.computeFreeVars$$anonfun$1$$anonfun$1$$anonfun$1$$anonfun$1(Dependencies.scala:283)
	at scala.collection.mutable.LinkedHashSet.foreach(LinkedHashSet.scala:128)
	at dotty.tools.dotc.transform.Dependencies.computeFreeVars$$anonfun$1$$anonfun$1$$anonfun$1(Dependencies.scala:281)
	at scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
	at scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
	at scala.Option.foreach(Option.scala:437)
	at dotty.tools.dotc.transform.Dependencies.computeFreeVars$$anonfun$1$$anonfun$1(Dependencies.scala:280)
	at scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
	at scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
	at scala.collection.mutable.LinkedHashSet.foreach(LinkedHashSet.scala:128)
	at dotty.tools.dotc.transform.Dependencies.computeFreeVars$$anonfun$1(Dependencies.scala:279)
	at scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
	at scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
	at scala.collection.IterableOnceOps.foreach(IterableOnce.scala:619)
	at scala.collection.IterableOnceOps.foreach$(IterableOnce.scala:617)
	at scala.collection.AbstractIterable.foreach(Iterable.scala:935)
	at dotty.tools.dotc.transform.Dependencies.computeFreeVars(Dependencies.scala:278)
	at dotty.tools.dotc.transform.Dependencies.<init>(Dependencies.scala:310)
	at dotty.tools.dotc.transform.LambdaLift$Lifter$$anon$1.<init>(LambdaLift.scala:38)
	at dotty.tools.dotc.transform.LambdaLift$Lifter.<init>(LambdaLift.scala:51)
	at dotty.tools.dotc.transform.LambdaLift.prepareForUnit(LambdaLift.scala:278)
	at dotty.tools.dotc.transform.MegaPhase.prepUnit(MegaPhase.scala:1107)
	at dotty.tools.dotc.transform.MegaPhase.transformUnit(MegaPhase.scala:480)
	at dotty.tools.dotc.transform.MegaPhase.run(MegaPhase.scala:493)
	at dotty.tools.dotc.core.Phases$Phase.runOn$$anonfun$1(Phases.scala:383)
	at scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
	at scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
	at scala.collection.immutable.List.foreach(List.scala:334)
	at dotty.tools.dotc.core.Phases$Phase.runOn(Phases.scala:376)
	at dotty.tools.dotc.Run.runPhases$1$$anonfun$1(Run.scala:367)
	at scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
	at scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
	at scala.collection.ArrayOps$.foreach$extension(ArrayOps.scala:1324)
	at dotty.tools.dotc.Run.runPhases$1(Run.scala:360)
	at dotty.tools.dotc.Run.compileUnits$$anonfun$1$$anonfun$2(Run.scala:407)
	at dotty.tools.dotc.Run.compileUnits$$anonfun$1$$anonfun$adapted$1(Run.scala:407)
	at scala.Function0.apply$mcV$sp(Function0.scala:42)
	at dotty.tools.dotc.Run.showProgress(Run.scala:469)
	at dotty.tools.dotc.Run.compileUnits$$anonfun$1(Run.scala:407)
	at dotty.tools.dotc.Run.compileUnits$$anonfun$adapted$1(Run.scala:419)
	at dotty.tools.dotc.util.Stats$.maybeMonitored(Stats.scala:69)
	at dotty.tools.dotc.Run.compileUnits(Run.scala:419)
	at dotty.tools.dotc.Run.compileUnits(Run.scala:312)
	at dotty.tools.dotc.Run.compileSuspendedUnits(Run.scala:433)
	at dotty.tools.dotc.Driver.finish(Driver.scala:63)
	at dotty.tools.dotc.Driver.doCompile(Driver.scala:38)
	at dotty.tools.dotc.Driver.process(Driver.scala:201)
	at dotty.tools.dotc.Driver.process(Driver.scala:169)
	at dotty.tools.dotc.Driver.process(Driver.scala:181)
	at dotty.tools.dotc.Driver.main(Driver.scala:211)
	at dotty.tools.MainGenericCompiler$.run$1(MainGenericCompiler.scala:162)
	at dotty.tools.MainGenericCompiler$.main(MainGenericCompiler.scala:186)
	at dotty.tools.MainGenericCompiler.main(MainGenericCompiler.scala)
@TomasMikula TomasMikula added itype:bug itype:crash stat:needs triage Every issue needs to have an "area" and "itype" label labels Jun 3, 2025
@Gedochao Gedochao added area:parser area:metaprogramming:quotes Issues related to quotes and splices area:lambda-lift and removed stat:needs triage Every issue needs to have an "area" and "itype" label labels Jun 4, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants