Skip to content

Error in reify/seal implementation #5533

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

Closed
liufengyun opened this issue Nov 28, 2018 · 1 comment
Closed

Error in reify/seal implementation #5533

liufengyun opened this issue Nov 28, 2018 · 1 comment

Comments

@liufengyun
Copy link
Contributor

liufengyun commented Nov 28, 2018

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
@nicolasstucki
Copy link
Contributor

Can be minimized to

import scala.quoted._
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._
    val tree = condition.unseal
    val expr = tree.seal[Boolean]
    '(println(~expr))
  }
}
class Test {
  import scalatest._
  val x = "String"
  def f(x: Int): Boolean = false
  def f(x: String): Boolean = true
  assert(f("abc"))
}

liufengyun added a commit that referenced this issue Nov 29, 2018
Fix #5533: Check conformance of subtype directly
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