Skip to content

Fix #5533: Check conformance of subtype directly #5539

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

Merged
merged 2 commits into from
Nov 29, 2018
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 7 additions & 23 deletions compiler/src/dotty/tools/dotc/tastyreflect/QuotedOpsImpl.scala
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
package dotty.tools.dotc.tastyreflect

import dotty.tools.dotc.core.Contexts.FreshContext
import dotty.tools.dotc.core.quoted.PickledQuotes
import dotty.tools.dotc.reporting.Reporter
import dotty.tools.dotc.reporting.diagnostic.MessageContainer

trait QuotedOpsImpl extends scala.tasty.reflect.QuotedOps with CoreImpl {

Expand All @@ -18,30 +15,17 @@ trait QuotedOpsImpl extends scala.tasty.reflect.QuotedOps with CoreImpl {
def TermToQuoteDeco(term: Term): TermToQuotedAPI = new TermToQuotedAPI {

def seal[T: scala.quoted.Type](implicit ctx: Context): scala.quoted.Expr[T] = {
typecheck(ctx)
typecheck()
new scala.quoted.Exprs.TastyTreeExpr(term).asInstanceOf[scala.quoted.Expr[T]]
}

private def typecheck[T: scala.quoted.Type](ctx: Context): Unit = {
implicit val ctx0: FreshContext = ctx.fresh
ctx0.setTyperState(ctx0.typerState.fresh())
ctx0.typerState.setReporter(new Reporter {
def doReport(m: MessageContainer)(implicit ctx: Context): Unit = ()
})
val tp = QuotedTypeDeco(implicitly[scala.quoted.Type[T]]).unseal
ctx0.typer.typed(term, tp.tpe)
if (ctx0.reporter.hasErrors) {
val stack = new Exception().getStackTrace
def filter(elem: StackTraceElement) =
elem.getClassName.startsWith("dotty.tools.dotc.tasty.ReflectionImpl") ||
!elem.getClassName.startsWith("dotty.tools.dotc")
private def typecheck[T: scala.quoted.Type]()(implicit ctx: Context): Unit = {
val tpt = QuotedTypeDeco(implicitly[scala.quoted.Type[T]]).unseal
if (!(term.tpe <:< tpt.tpe)) {
throw new scala.tasty.TastyTypecheckError(
s"""Error during tasty reflection while typing term
|term: ${term.show}
|with expected type: ${tp.tpe.show}
|
| ${stack.takeWhile(filter).mkString("\n ")}
""".stripMargin
s"""Term: ${term.show}
|did not conform to type: ${tpt.tpe.show}
|""".stripMargin
)
}
}
Expand Down
2 changes: 1 addition & 1 deletion library/src/scala/tasty/TastyTypecheckError.scala
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
package scala.tasty

class TastyTypecheckError(msg: String) extends Throwable
class TastyTypecheckError(msg: String) extends Throwable(msg)
1 change: 1 addition & 0 deletions tests/run-separate-compilation/i5533.check
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
true
20 changes: 20 additions & 0 deletions tests/run-separate-compilation/i5533/Macro_1.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import scala.quoted._
import scala.tasty._

object scalatest {

def f(x: Int): Boolean = false
def f(x: String): Boolean = true

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))
}
}
9 changes: 9 additions & 0 deletions tests/run-separate-compilation/i5533/Test_2.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
object Test {

def main(args: Array[String]): Unit = {
import scalatest._
val x = "String"
assert(f("abc"))
}

}
3 changes: 3 additions & 0 deletions tests/run-separate-compilation/i5533b.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
String
String
()
34 changes: 34 additions & 0 deletions tests/run-separate-compilation/i5533b/Macro_1.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
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.unseal
def exprStr: String = condition.show

tree.underlyingArgument match {
case Term.Apply(Term.Select(lhs, op, _), rhs :: Nil) =>
val left = lhs.seal[Any]
val right = rhs.seal[Any]
op match {
case "==" =>
'{
val _left = ~left
val _right = ~right
val _result = _left == _right
println(_left)
println(_right)
scala.Predef.assert(_result)
}
}
}
}
}
9 changes: 9 additions & 0 deletions tests/run-separate-compilation/i5533b/Test_2.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
object Test {

def main(args: Array[String]): Unit = {
import scalatest._
val x = "String"
println(assert(f(x) == "String"))
}

}