Skip to content
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

-Xcheck-macro does not check for incorrectly constructed TypeRefs or TermRefs #22151

Open
jchyb opened this issue Dec 5, 2024 · 0 comments
Open
Labels
area:metaprogramming:other Issues tied to metaprogramming/macros not covered by the other labels. itype:bug

Comments

@jchyb
Copy link
Contributor

jchyb commented Dec 5, 2024

Compiler version

any

Minimized code

Incorrect TypeRef example:

import scala.quoted.*

object Macros {
  def valuesImpl[A: Type](using Quotes): Expr[Unit] = {
    import quotes.reflect.*
    val typeRef = TypeRepr.of[A].select(Symbol.classSymbol("scala.collection.immutable.List").companionModule.methodMember("apply").head)
    val symbol = Symbol.newVal(Symbol.spliceOwner, "test", typeRef, Flags.EmptyFlags, Symbol.noSymbol)
    Block(List(ValDef(symbol, Some('{???}.asTerm))), '{???}.asTerm).asExprOf[Unit]
  }

  transparent inline def values[A]: Unit = ${ valuesImpl[A] }
}
object Obj

@main def Test() =
  Macros.values[Obj.type]

Incorrect TermRef code

import scala.quoted.*

object Macros {
  def valuesImpl[A: Type](using Quotes): Expr[List[A]] = {
    import quotes.reflect.*

    val exprList = TypeRepr.of[A].typeSymbol.children.flatMap { symbol =>
      // Illegal termRef, not caught with -Xcheck-macros
      val termRef = TypeRepr.of[A].typeSymbol.owner.typeRef.select(symbol)

      println(termRef)
      termRef match
        case termRef: TermRef =>
          Some(Ref.term(termRef).asExprOf[A])
        case _  =>
          None
    }
    Expr.ofList(exprList)
  }

  transparent inline def values[A]: List[A] = ${ valuesImpl[A] }
}
object Obj:
  enum Foo:
    case Bar
@main def Test() =
  println(Macros.values[Obj.Foo])

Incorrectness of neither of those is reported by -Xcheck-macro, instead leading to a crash

Output

Incorrect TypeRef code

  unhandled exception while running erasure on TypeRefCrashTest.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: TypeRefCrashTest.scala
        during phase: erasure
                mode: Mode(ImplicitsEnabled)
     library version: version 2.13.15
    compiler version: version 3.6.3-RC1-bin-SNAPSHOT-nonbootstrapped-git-898f952
            settings: -Xcheck-macros true -classpath /Users/jchyb/Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala-library/2.13.15/scala-library-2.13.15.jar:/Users/jchyb/workspace/scala3/library/../out/bootstrap/scala3-library-bootstrapped/scala-3.6.3-RC1-bin-SNAPSHOT-nonbootstrapped/scala3-library_3-3.6.3-RC1-bin-SNAPSHOT.jar

  Exception while compiling TypeRefCrash.scala, TypeRefCrashTest.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.15
    compiler version: version 3.6.3-RC1-bin-SNAPSHOT-nonbootstrapped-git-898f952
            settings: -Xcheck-macros true -classpath /Users/jchyb/Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala-library/2.13.15/scala-library-2.13.15.jar:/Users/jchyb/workspace/scala3/library/../out/bootstrap/scala3-library-bootstrapped/scala-3.6.3-RC1-bin-SNAPSHOT-nonbootstrapped/scala3-library_3-3.6.3-RC1-bin-SNAPSHOT.jar
Exception in thread "main" java.lang.AssertionError: assertion failed: bad cast: ???().asInstanceOf[<notype>]
        at scala.runtime.Scala3RunTime$.assertFailed(Scala3RunTime.scala:8)
        at dotty.tools.dotc.ast.tpd$TreeOps$.asInstance$extension(tpd.scala:1041)
        at dotty.tools.dotc.transform.Erasure$Boxing$.cast(Erasure.scala:375)
        at dotty.tools.dotc.transform.Erasure$Boxing$.adaptToType(Erasure.scala:410)
        at dotty.tools.dotc.transform.Erasure$Typer.adapt(Erasure.scala:1103)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3662)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3666)
        at dotty.tools.dotc.typer.ReTyper.typedInlined(ReTyper.scala:100)
        at dotty.tools.dotc.transform.Erasure$Typer.typedInlined(Erasure.scala:914)
        at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:3523)
        at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3585)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3662)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3659)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3666)
        at dotty.tools.dotc.typer.Typer.typedExpr(Typer.scala:3777)
        at dotty.tools.dotc.typer.Typer.typedValDef(Typer.scala:2838)
        at dotty.tools.dotc.transform.Erasure$Typer.typedValDef(Erasure.scala:923)
        at dotty.tools.dotc.typer.Typer.typedNamed$1(Typer.scala:3479)
        at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3584)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3662)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3666)
        at dotty.tools.dotc.typer.Typer.traverse$1(Typer.scala:3688)
        at dotty.tools.dotc.typer.Typer.typedStats(Typer.scala:3734)
        at dotty.tools.dotc.transform.Erasure$Typer.typedStats(Erasure.scala:1085)
        at dotty.tools.dotc.typer.Typer.typedBlockStats(Typer.scala:1430)
        at dotty.tools.dotc.typer.Typer.typedBlock(Typer.scala:1434)
        at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:3508)
        at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3585)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3662)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3666)
        at dotty.tools.dotc.typer.ReTyper.typedInlined(ReTyper.scala:100)
        at dotty.tools.dotc.transform.Erasure$Typer.typedInlined(Erasure.scala:914)
        at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:3523)
        at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3585)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3662)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3666)
        at dotty.tools.dotc.typer.Typer.typedExpr(Typer.scala:3777)
        at dotty.tools.dotc.typer.Typer.$anonfun$66(Typer.scala:2901)
        at dotty.tools.dotc.inlines.PrepareInlineable$.dropInlineIfError(PrepareInlineable.scala:256)
        at dotty.tools.dotc.typer.Typer.typedDefDef(Typer.scala:2901)
        at dotty.tools.dotc.transform.Erasure$Typer.typedDefDef(Erasure.scala:972)
        at dotty.tools.dotc.typer.Typer.typedNamed$1(Typer.scala:3482)
        at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3584)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3662)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3666)
        at dotty.tools.dotc.typer.Typer.traverse$1(Typer.scala:3688)
        at dotty.tools.dotc.typer.Typer.typedStats(Typer.scala:3734)
        at dotty.tools.dotc.transform.Erasure$Typer.typedStats(Erasure.scala:1085)
        at dotty.tools.dotc.typer.Typer.typedClassDef(Typer.scala:3167)
        at dotty.tools.dotc.transform.Erasure$Typer.typedClassDef(Erasure.scala:1061)
        at dotty.tools.dotc.typer.Typer.typedTypeOrClassDef$1(Typer.scala:3488)
        at dotty.tools.dotc.typer.Typer.typedNamed$1(Typer.scala:3492)
        at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3584)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3662)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3666)
        at dotty.tools.dotc.typer.Typer.traverse$1(Typer.scala:3688)
        at dotty.tools.dotc.typer.Typer.typedStats(Typer.scala:3734)
        at dotty.tools.dotc.transform.Erasure$Typer.typedStats(Erasure.scala:1085)
        at dotty.tools.dotc.typer.Typer.typedPackageDef(Typer.scala:3300)
        at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:3534)
        at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:3585)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3662)
        at dotty.tools.dotc.typer.Typer.typed(Typer.scala:3666)
        at dotty.tools.dotc.typer.Typer.typedExpr(Typer.scala:3777)
        at dotty.tools.dotc.transform.Erasure.run(Erasure.scala:146)
        at dotty.tools.dotc.core.Phases$Phase.runOn$$anonfun$1(Phases.scala:380)
        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:373)
        at dotty.tools.dotc.Run.runPhases$1$$anonfun$1(Run.scala:343)
        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:1323)
        at dotty.tools.dotc.Run.runPhases$1(Run.scala:336)
        at dotty.tools.dotc.Run.compileUnits$$anonfun$1(Run.scala:383)
        at dotty.tools.dotc.Run.compileUnits$$anonfun$adapted$1(Run.scala:395)
        at dotty.tools.dotc.util.Stats$.maybeMonitored(Stats.scala:69)
        at dotty.tools.dotc.Run.compileUnits(Run.scala:395)
        at dotty.tools.dotc.Run.compileUnits(Run.scala:288)
        at dotty.tools.dotc.Run.compileSuspendedUnits(Run.scala:409)
        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.dotc.Main.main(Main.scala)

Incorrect TermRef code

java.util.NoSuchElementException: val Bar
        at scala.collection.mutable.AnyRefMap$ExceptionDefault.apply(AnyRefMap.scala:527)
        at scala.collection.mutable.AnyRefMap$ExceptionDefault.apply(AnyRefMap.scala:526)
        at scala.collection.mutable.AnyRefMap.apply(AnyRefMap.scala:207)
        at dotty.tools.backend.jvm.BCodeSkelBuilder$PlainSkelBuilder$locals$.load(BCodeSkelBuilder.scala:583)
        at dotty.tools.backend.jvm.BCodeBodyBuilder$PlainBodyBuilder.genLoadTo(BCodeBodyBuilder.scala:439)
        at dotty.tools.backend.jvm.BCodeBodyBuilder$PlainBodyBuilder.genLoad(BCodeBodyBuilder.scala:303)
        at dotty.tools.backend.jvm.BCodeBodyBuilder$PlainBodyBuilder.loop$1(BCodeBodyBuilder.scala:1209)
        at dotty.tools.backend.jvm.BCodeBodyBuilder$PlainBodyBuilder.genLoadArguments(BCodeBodyBuilder.scala:1216)
        at dotty.tools.backend.jvm.BCodeBodyBuilder$PlainBodyBuilder.genApply(BCodeBodyBuilder.scala:798)
        at dotty.tools.backend.jvm.BCodeBodyBuilder$PlainBodyBuilder.genLoadTo(BCodeBodyBuilder.scala:385)
        at dotty.tools.backend.jvm.BCodeBodyBuilder$PlainBodyBuilder.genLoad(BCodeBodyBuilder.scala:303)
        at dotty.tools.backend.jvm.BCodeBodyBuilder$PlainBodyBuilder.genLoad(BCodeBodyBuilder.scala:297)
        at dotty.tools.backend.jvm.BCodeBodyBuilder$PlainBodyBuilder.genLoadQualifier(BCodeBodyBuilder.scala:1191)
        at dotty.tools.backend.jvm.BCodeBodyBuilder$PlainBodyBuilder.genTypeApply(BCodeBodyBuilder.scala:694)
        at dotty.tools.backend.jvm.BCodeBodyBuilder$PlainBodyBuilder.genLoadTo(BCodeBodyBuilder.scala:483)
        at dotty.tools.backend.jvm.BCodeBodyBuilder$PlainBodyBuilder.genLoad(BCodeBodyBuilder.scala:303)
        at dotty.tools.backend.jvm.BCodeBodyBuilder$PlainBodyBuilder.loop$1(BCodeBodyBuilder.scala:1209)
        at dotty.tools.backend.jvm.BCodeBodyBuilder$PlainBodyBuilder.genLoadArguments(BCodeBodyBuilder.scala:1216)
        at dotty.tools.backend.jvm.BCodeBodyBuilder$PlainBodyBuilder.genApply(BCodeBodyBuilder.scala:835)
        at dotty.tools.backend.jvm.BCodeBodyBuilder$PlainBodyBuilder.genLoadTo(BCodeBodyBuilder.scala:385)
        at dotty.tools.backend.jvm.BCodeSkelBuilder$PlainSkelBuilder.emitNormalMethodBody$1(BCodeSkelBuilder.scala:899)
        at dotty.tools.backend.jvm.BCodeSkelBuilder$PlainSkelBuilder.genDefDef(BCodeSkelBuilder.scala:922)
        at dotty.tools.backend.jvm.BCodeSkelBuilder$PlainSkelBuilder.gen(BCodeSkelBuilder.scala:699)
        at dotty.tools.backend.jvm.BCodeSkelBuilder$PlainSkelBuilder.gen$$anonfun$1(BCodeSkelBuilder.scala:705)
        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.backend.jvm.BCodeSkelBuilder$PlainSkelBuilder.gen(BCodeSkelBuilder.scala:705)
        at dotty.tools.backend.jvm.BCodeSkelBuilder$PlainSkelBuilder.genPlainClass(BCodeSkelBuilder.scala:293)
        at dotty.tools.backend.jvm.CodeGen.genClass(CodeGen.scala:160)
        at dotty.tools.backend.jvm.CodeGen.genClassDef$1(CodeGen.scala:62)
        at dotty.tools.backend.jvm.CodeGen.genClassDefs$1(CodeGen.scala:117)
        at dotty.tools.backend.jvm.CodeGen.genClassDefs$1$$anonfun$1(CodeGen.scala:115)
        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.backend.jvm.CodeGen.genClassDefs$1(CodeGen.scala:115)
        at dotty.tools.backend.jvm.CodeGen.genUnit(CodeGen.scala:120)
        at dotty.tools.backend.jvm.GenBCode.run(GenBCode.scala:90)
        at dotty.tools.dotc.core.Phases$Phase.runOn$$anonfun$1(Phases.scala:380)
        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:373)
        at dotty.tools.backend.jvm.GenBCode.runOn(GenBCode.scala:98)
        at dotty.tools.dotc.Run.runPhases$1$$anonfun$1(Run.scala:343)
        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:1323)
        at dotty.tools.dotc.Run.runPhases$1(Run.scala:336)
        at dotty.tools.dotc.Run.compileUnits$$anonfun$1(Run.scala:383)
        at dotty.tools.dotc.Run.compileUnits$$anonfun$adapted$1(Run.scala:395)
        at dotty.tools.dotc.util.Stats$.maybeMonitored(Stats.scala:69)
        at dotty.tools.dotc.Run.compileUnits(Run.scala:395)
        at dotty.tools.dotc.Run.compileUnits(Run.scala:288)
        at dotty.tools.dotc.Run.compileSuspendedUnits(Run.scala:409)
        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.dotc.Main.main(Main.scala)

Expectation

-Xcheck-macro error

@jchyb jchyb added itype:bug stat:needs triage Every issue needs to have an "area" and "itype" label labels Dec 5, 2024
@Gedochao Gedochao added area:metaprogramming:other Issues tied to metaprogramming/macros not covered by the other labels. and removed stat:needs triage Every issue needs to have an "area" and "itype" label labels Dec 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:metaprogramming:other Issues tied to metaprogramming/macros not covered by the other labels. itype:bug
Projects
None yet
Development

No branches or pull requests

2 participants