summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Macros.scala4
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala13
-rw-r--r--test/files/run/t5418a.check1
-rw-r--r--test/files/run/t5418a.scala3
-rw-r--r--test/files/run/t5418b.check2
-rw-r--r--test/files/run/t5418b.scala11
6 files changed, 31 insertions, 3 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
index 9adf86e44b..f9a35ba9a0 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
@@ -710,7 +710,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces {
if (isNullaryInvocation(expandee)) expectedTpe = expectedTpe.finalResultType
var typechecked = typecheck("macro def return type", expanded, expectedTpe)
typechecked = typecheck("expected type", typechecked, pt)
- typechecked updateAttachment MacroExpansionAttachment(expandee)
+ typechecked
} finally {
popMacroContext()
}
@@ -776,7 +776,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces {
macroLogLite("" + expanded.tree + "\n" + showRaw(expanded.tree))
val freeSyms = expanded.tree.freeTerms ++ expanded.tree.freeTypes
freeSyms foreach (sym => MacroFreeSymbolError(expandee, sym))
- Success(atPos(enclosingMacroPosition.focus)(expanded.tree))
+ Success(atPos(enclosingMacroPosition.focus)(expanded.tree updateAttachment MacroExpansionAttachment(expandee)))
case _ =>
MacroExpansionIsNotExprError(expandee, expanded)
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index ae08a9f64d..9b93c7a214 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -1197,7 +1197,7 @@ trait Typers extends Modes with Adaptations with Tags {
val found = tree.tpe
if (!found.isErroneous && !pt.isErroneous) {
- if (!context.reportErrors && isPastTyper) {
+ if ((!context.reportErrors && isPastTyper) || tree.attachments.get[MacroExpansionAttachment].isDefined) {
val (bound, req) = pt match {
case ExistentialType(qs, tpe) => (qs, tpe)
case _ => (Nil, pt)
@@ -1230,6 +1230,17 @@ trait Typers extends Modes with Adaptations with Tags {
// to consistently transform skolems and fix 6029), I'd like to
// investigate ways to avoid skolems completely.
//
+ // upd. The same problem happens when we try to typecheck the result of macro expansion against its expected type
+ // (which is the return type of the macro definition instantiated in the context of expandee):
+ //
+ // Test.scala:2: error: type mismatch;
+ // found : $u.Expr[Class[_ <: Object]]
+ // required: reflect.runtime.universe.Expr[Class[?0(in value <local Test>)]] where type ?0(in value <local Test>) <: Object
+ // scala.reflect.runtime.universe.reify(new Object().getClass)
+ // ^
+ // Therefore following Martin's advice I use this logic to recover from skolem errors after macro expansions
+ // (by adding the ` || tree.attachments.get[MacroExpansionAttachment].isDefined` clause to the conditional above).
+ //
log("recovering from existential or skolem type error in tree \n" + tree + "\nwith type " + tree.tpe + "\n expected type = " + pt + "\n context = " + context.tree)
return adapt(tree, mode, deriveTypeWithWildcards(boundOrSkolems)(pt))
}
diff --git a/test/files/run/t5418a.check b/test/files/run/t5418a.check
new file mode 100644
index 0000000000..ee0e80e11f
--- /dev/null
+++ b/test/files/run/t5418a.check
@@ -0,0 +1 @@
+Expr[Class[_ <: java.lang.Object]](new Object().getClass())
diff --git a/test/files/run/t5418a.scala b/test/files/run/t5418a.scala
new file mode 100644
index 0000000000..90bc542be6
--- /dev/null
+++ b/test/files/run/t5418a.scala
@@ -0,0 +1,3 @@
+object Test extends App {
+ println(scala.reflect.runtime.universe.reify(new Object().getClass))
+} \ No newline at end of file
diff --git a/test/files/run/t5418b.check b/test/files/run/t5418b.check
new file mode 100644
index 0000000000..875ad08435
--- /dev/null
+++ b/test/files/run/t5418b.check
@@ -0,0 +1,2 @@
+new Object().getClass()
+TypeRef(ThisType(java.lang), java.lang.Class, List(TypeRef(NoPrefix, newTypeName("?0"), List())))
diff --git a/test/files/run/t5418b.scala b/test/files/run/t5418b.scala
new file mode 100644
index 0000000000..08e8bb163b
--- /dev/null
+++ b/test/files/run/t5418b.scala
@@ -0,0 +1,11 @@
+import scala.reflect.runtime.universe._
+import scala.reflect.runtime.{currentMirror => cm}
+import scala.tools.reflect.ToolBox
+
+object Test extends App {
+ val tb = cm.mkToolBox()
+ val untyped = reify(new Object().getClass).tree
+ val typed = tb.typeCheck(untyped)
+ println(typed)
+ println(showRaw(typed.tpe))
+} \ No newline at end of file