Skip to content

Error in reify/seal implementation (2) #5536

@liufengyun

Description

@liufengyun

Another exception encountered while developing ScalaTest macros. Related #5533

It is minimized as follows:

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

object scalatest {
  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 Equalizer[L](val leftSide: L) {
  def ===(literalNull: Null): Boolean = leftSide == null
}

object Equality {
  implicit def toEqualizer[T](x: T): Equalizer[T] = new Equalizer(x)
}


class Test {
  import scalatest._
  import Equality._

  val x = "String"

  assert(x === null)
}

The key to reproduce the problem is the def === extension method.

error log
-- Error: macros/test_2.scala:16:8 ---------------------------------------------
16 |  assert(x === null)
   |  ^^^^^^^^^^^^^^^^^^
   |An exception occurred while executing macro expansion
   |null
   |scala.tasty.TastyTypecheckError
   |	at dotty.tools.dotc.tastyreflect.QuotedOpsImpl$$anon$4.typecheck(QuotedOpsImpl.scala:43)
   |	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:16)
   |	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