Skip to content

Error in reify/seal implementation #5533

Closed
@liufengyun

Description

@liufengyun

An exception encountered while developing ScalaTest macros.

It is minimized as follows:

// file macro_1.scala
import scala.quoted._
import scala.tasty._

object scalatest {
  def f(x: Int): Int = x
  def f(x: String): String = x

  inline def assert(condition: => Boolean): Unit = ~assertImpl('(condition))

  def assertImpl(condition: Expr[Boolean])(implicit refl: Reflection): Expr[Unit] = {
    import refl._
    import quoted.Toolbox.Default._

    val tree = condition.reflect
    def exprStr: String = condition.show

    tree.underlyingArgument match {
      case Term.Apply(Term.Select(lhs, op, _), rhs :: Nil) =>
        val left = lhs.reify[Any]
        val right = rhs.reify[Any]
        op match {
          case "==" =>
            '{
              val _left   = ~left
              val _right  = ~right
              val _result = _left == _right
              scala.Predef.assert(_result)
            }
        }
    }
  }
}

// file test_2.scala
class Test {
  import scalatest._
  val x = "String"

  assert(f(x) == "a")
}

The key to reproduce the problem is that f should be overloaded.

error log
-- Error: macros/test_2.scala:5:8 ----------------------------------------------
5 |  assert(f(x) == "a")
  |  ^^^^^^^^^^^^^^^^^^^
  |An exception occurred while executing macro expansion
  |assertion failed: TermRef(TermRef(ThisType(TypeRef(NoPrefix,module class )),module scalatest),f)
  |java.lang.AssertionError: assertion failed: TermRef(TermRef(ThisType(TypeRef(NoPrefix,module class )),module scalatest),f)
  |	at scala.Predef$.assert(Predef.scala:219)
  |	at dotty.tools.dotc.core.Types$NamedType.setDenot(Types.scala:1893)
  |	at dotty.tools.dotc.core.Types$NamedType.withDenot(Types.scala:2117)
  |	at dotty.tools.dotc.core.Types$TermRef$.apply(Types.scala:2288)
  |	at dotty.tools.dotc.core.Types$NamedType$.apply(Types.scala:2274)
  |	at dotty.tools.dotc.core.Types$Type.select(Types.scala:1246)
  |	at dotty.tools.dotc.typer.Typer.selection$1(Typer.scala:198)
  |	at dotty.tools.dotc.typer.Typer.wildImportRef$1(Typer.scala:239)
  |	at dotty.tools.dotc.typer.Typer.loop$1(Typer.scala:330)
  |	at dotty.tools.dotc.typer.Typer.findRef$1(Typer.scala:349)
  |	at dotty.tools.dotc.typer.Typer.$anonfun$typedIdent$1(Typer.scala:368)
  |	at dotty.tools.dotc.util.Stats$.track(Stats.scala:37)
  |	at dotty.tools.dotc.typer.Typer.typedIdent(Typer.scala:117)
  |	at dotty.tools.dotc.typer.Typer.typedNamed$1(Typer.scala:1868)
  |	at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:1942)
  |	at dotty.tools.dotc.typer.Typer.$anonfun$typed$2(Typer.scala:1974)
  |	at dotty.tools.dotc.reporting.trace$.apply(trace.scala:40)
  |	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:1970)
  |	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:1986)
  |	at dotty.tools.dotc.typer.Typer.typedExpr(Typer.scala:2049)
  |	at dotty.tools.dotc.typer.Applications.$anonfun$typedApply$1(Applications.scala:743)
  |	at dotty.tools.dotc.util.Stats$.track(Stats.scala:37)
  |	at dotty.tools.dotc.typer.Applications.realApply$1(Applications.scala:741)
  |	at dotty.tools.dotc.typer.Applications.typedApply(Applications.scala:842)
  |	at dotty.tools.dotc.typer.Applications.typedApply$(Applications.scala:739)
  |	at dotty.tools.dotc.typer.Typer.typedApply(Typer.scala:79)
  |	at dotty.tools.dotc.typer.Typer.typedUnnamed$1(Typer.scala:1889)
  |	at dotty.tools.dotc.typer.Typer.typedUnadapted(Typer.scala:1943)
  |	at dotty.tools.dotc.typer.Typer.$anonfun$typed$2(Typer.scala:1974)
  |	at dotty.tools.dotc.reporting.trace$.apply(trace.scala:40)
  |	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:1970)
  |	at dotty.tools.dotc.typer.Typer.typed(Typer.scala:1986)
  |	at dotty.tools.dotc.tastyreflect.QuotedOpsImpl$$anon$4.typecheck(QuotedOpsImpl.scala:32)
  |	at dotty.tools.dotc.tastyreflect.QuotedOpsImpl$$anon$4.reify(QuotedOpsImpl.scala:21)
  |	at dotty.tools.dotc.tastyreflect.QuotedOpsImpl$$anon$4.reify(QuotedOpsImpl.scala:18)
  |	at scalatest$.assertImpl(assert_1.scala:19)
  |	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.dotc.transform.Splicer$Interpreter.$anonfun$interpretStaticMethodCall$1(Splicer.scala:124)
  |	at dotty.tools.dotc.transform.Splicer$Interpreter.stopIfRuntimeException(Splicer.scala:172)
  |	at dotty.tools.dotc.transform.Splicer$Interpreter.interpretStaticMethodCall(Splicer.scala:124)
  |	at dotty.tools.dotc.transform.Splicer$AbstractInterpreter.interpretTree(Splicer.scala:318)
  |	at dotty.tools.dotc.transform.Splicer$Interpreter.interpret(Splicer.scala:83)
  |	at dotty.tools.dotc.transform.Splicer$.splice(Splicer.scala:44)
  |	at dotty.tools.dotc.transform.Staging$Reifier.splice(Staging.scala:440)
  |	at dotty.tools.dotc.transform.Staging$Reifier.$anonfun$transform$2(Staging.scala:569)
  |	at dotty.tools.dotc.reporting.trace$.apply(trace.scala:40)
  |	at dotty.tools.dotc.reporting.trace$.apply(trace.scala:48)
  |	at dotty.tools.dotc.transform.Staging$Reifier.transform(Staging.scala:554)
  |	at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1214)
  |	at dotty.tools.dotc.transform.MacroTransform$Transformer.transform(MacroTransform.scala:62)
  |	at dotty.tools.dotc.transform.MacroTransformWithImplicits$ImplicitsTransformer.transform(MacroTransformWithImplicits.scala:83)
  |	at dotty.tools.dotc.transform.Staging$Reifier.super$transform(Staging.scala:556)
  |	at dotty.tools.dotc.transform.Staging$Reifier.mapOverTree$1(Staging.scala:556)
  |	at dotty.tools.dotc.transform.Staging$Reifier.$anonfun$transform$2(Staging.scala:613)
  |	at dotty.tools.dotc.reporting.trace$.apply(trace.scala:40)
  |	at dotty.tools.dotc.reporting.trace$.apply(trace.scala:48)
  |	at dotty.tools.dotc.transform.Staging$Reifier.transform(Staging.scala:554)
  |	at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1240)
  |	at dotty.tools.dotc.transform.MacroTransform$Transformer.transform(MacroTransform.scala:62)
  |	at dotty.tools.dotc.transform.MacroTransformWithImplicits$ImplicitsTransformer.transform(MacroTransformWithImplicits.scala:83)
  |	at dotty.tools.dotc.transform.Staging$Reifier.super$transform(Staging.scala:556)
  |	at dotty.tools.dotc.transform.Staging$Reifier.mapOverTree$1(Staging.scala:556)
  |	at dotty.tools.dotc.transform.Staging$Reifier.$anonfun$transform$2(Staging.scala:613)
  |	at dotty.tools.dotc.reporting.trace$.apply(trace.scala:40)
  |	at dotty.tools.dotc.reporting.trace$.apply(trace.scala:48)
  |	at dotty.tools.dotc.transform.Staging$Reifier.transform(Staging.scala:554)
  |	at dotty.tools.dotc.transform.MacroTransformWithImplicits$ImplicitsTransformer.traverse$1(MacroTransformWithImplicits.scala:50)
  |	at dotty.tools.dotc.transform.MacroTransformWithImplicits$ImplicitsTransformer.transformStats(MacroTransformWithImplicits.scala:57)
  |	at dotty.tools.dotc.transform.MacroTransform$Transformer.transform(MacroTransform.scala:60)
  |	at dotty.tools.dotc.transform.MacroTransformWithImplicits$ImplicitsTransformer.transform(MacroTransformWithImplicits.scala:83)
  |	at dotty.tools.dotc.transform.Staging$Reifier.super$transform(Staging.scala:556)
  |	at dotty.tools.dotc.transform.Staging$Reifier.mapOverTree$1(Staging.scala:556)
  |	at dotty.tools.dotc.transform.Staging$Reifier.$anonfun$transform$2(Staging.scala:613)
  |	at dotty.tools.dotc.reporting.trace$.apply(trace.scala:40)
  |	at dotty.tools.dotc.reporting.trace$.apply(trace.scala:48)
  |	at dotty.tools.dotc.transform.Staging$Reifier.transform(Staging.scala:554)
  |	at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1280)
  |	at dotty.tools.dotc.transform.MacroTransform$Transformer.transform(MacroTransform.scala:54)
  |	at dotty.tools.dotc.transform.MacroTransformWithImplicits$ImplicitsTransformer.transform(MacroTransformWithImplicits.scala:83)
  |	at dotty.tools.dotc.transform.Staging$Reifier.super$transform(Staging.scala:556)
  |	at dotty.tools.dotc.transform.Staging$Reifier.mapOverTree$1(Staging.scala:556)
  |	at dotty.tools.dotc.transform.Staging$Reifier.$anonfun$transform$2(Staging.scala:613)
  |	at dotty.tools.dotc.reporting.trace$.apply(trace.scala:40)
  |	at dotty.tools.dotc.reporting.trace$.apply(trace.scala:48)
  |	at dotty.tools.dotc.transform.Staging$Reifier.transform(Staging.scala:554)
  |	at dotty.tools.dotc.ast.Trees$Instance$TreeMap.$anonfun$transform$6(Trees.scala:1300)
  |	at scala.collection.immutable.List.mapConserve(List.scala:175)
  |	at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1300)
  |	at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transformStats(Trees.scala:1298)
  |	at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1286)
  |	at dotty.tools.dotc.transform.MacroTransform$Transformer.transform(MacroTransform.scala:54)
  |	at dotty.tools.dotc.transform.MacroTransformWithImplicits$ImplicitsTransformer.transform(MacroTransformWithImplicits.scala:83)
  |	at dotty.tools.dotc.transform.Staging$Reifier.super$transform(Staging.scala:556)
  |	at dotty.tools.dotc.transform.Staging$Reifier.mapOverTree$1(Staging.scala:556)
  |	at dotty.tools.dotc.transform.Staging$Reifier.$anonfun$transform$2(Staging.scala:613)
  |	at dotty.tools.dotc.reporting.trace$.apply(trace.scala:40)
  |	at dotty.tools.dotc.reporting.trace$.apply(trace.scala:48)
  |	at dotty.tools.dotc.transform.Staging$Reifier.transform(Staging.scala:554)
  |	at dotty.tools.dotc.transform.MacroTransform.run(MacroTransform.scala:21)
  |	at dotty.tools.dotc.transform.Staging.run(Staging.scala:91)
  |	at dotty.tools.dotc.core.Phases$Phase.$anonfun$runOn$1(Phases.scala:297)
  |	at scala.collection.immutable.List.map(List.scala:282)
  |	at dotty.tools.dotc.core.Phases$Phase.runOn(Phases.scala:295)
  |	at dotty.tools.dotc.core.Phases$Phase.runOn$(Phases.scala:294)
  |	at dotty.tools.dotc.transform.MacroTransform.runOn(MacroTransform.scala:15)
  |	at dotty.tools.dotc.Run.$anonfun$compileUnits$3(Run.scala:172)
  |	at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:12)
  |	at dotty.tools.dotc.util.Stats$.trackTime(Stats.scala:49)
  |	at dotty.tools.dotc.Run.$anonfun$compileUnits$2(Run.scala:169)
  |	at dotty.tools.dotc.Run.$anonfun$compileUnits$2$adapted(Run.scala:167)
  |	at scala.collection.IndexedSeqOptimized.foreach(IndexedSeqOptimized.scala:32)
  |	at scala.collection.IndexedSeqOptimized.foreach$(IndexedSeqOptimized.scala:29)
  |	at scala.collection.mutable.ArrayOps$ofRef.foreach(ArrayOps.scala:194)
  |	at dotty.tools.dotc.Run.runPhases$1(Run.scala:167)
  |	at dotty.tools.dotc.Run.$anonfun$compileUnits$1(Run.scala:192)
  |	at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:12)
  |	at dotty.tools.dotc.util.Stats$.maybeMonitored(Stats.scala:90)
  |	at dotty.tools.dotc.Run.compileUnits(Run.scala:147)
  |	at dotty.tools.dotc.Run.compileSources(Run.scala:134)
  |	at dotty.tools.dotc.Run.compile(Run.scala:118)
  |	at dotty.tools.dotc.Driver.doCompile(Driver.scala:30)
  |	at dotty.tools.dotc.Driver.process(Driver.scala:136)
  |	at dotty.tools.dotc.Driver.process(Driver.scala:105)
  |	at dotty.tools.dotc.Driver.process(Driver.scala:117)
  |	at dotty.tools.dotc.Driver.main(Driver.scala:144)
  |	at dotty.tools.dotc.Main.main(Main.scala)
  |
one error found

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions