summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/reflect/reify/Reifier.scala10
-rw-r--r--src/compiler/scala/tools/nsc/ast/Trees.scala16
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala2
-rw-r--r--test/files/run/macro-reify-chained1/Impls_Macros_1.scala (renamed from test/files/run/macro-reify-nested-b/Impls_Macros_1.scala)3
-rw-r--r--test/files/run/macro-reify-chained1/Test_2.scala9
-rw-r--r--test/files/run/macro-reify-chained2/Impls_Macros_1.scala47
-rw-r--r--test/files/run/macro-reify-chained2/Test_2.scala9
-rw-r--r--test/files/run/macro-reify-nested-a.flags1
-rw-r--r--test/files/run/macro-reify-nested-a1/Impls_Macros_1.scala (renamed from test/files/run/macro-reify-nested-a/Impls_Macros_1.scala)3
-rw-r--r--test/files/run/macro-reify-nested-a1/Test_2.scala (renamed from test/files/run/macro-reify-nested-a/Test_2.scala)5
-rw-r--r--test/files/run/macro-reify-nested-a2/Impls_Macros_1.scala47
-rw-r--r--test/files/run/macro-reify-nested-a2/Test_2.scala9
-rw-r--r--test/files/run/macro-reify-nested-b.flags1
-rw-r--r--test/files/run/macro-reify-nested-b1/Impls_Macros_1.scala47
-rw-r--r--test/files/run/macro-reify-nested-b1/Test_2.scala (renamed from test/files/run/macro-reify-nested-b/Test_2.scala)5
-rw-r--r--test/files/run/macro-reify-nested-b2/Impls_Macros_1.scala47
-rw-r--r--test/files/run/macro-reify-nested-b2/Test_2.scala9
17 files changed, 261 insertions, 9 deletions
diff --git a/src/compiler/scala/reflect/reify/Reifier.scala b/src/compiler/scala/reflect/reify/Reifier.scala
index 6b0a0ee8d7..b1cc797389 100644
--- a/src/compiler/scala/reflect/reify/Reifier.scala
+++ b/src/compiler/scala/reflect/reify/Reifier.scala
@@ -110,10 +110,18 @@ abstract class Reifier extends States
// todo. this is a common problem with non-trivial macros in our current macro system
// needs to be solved some day
// upd. a new hope: https://groups.google.com/forum/#!topic/scala-internals/TtCTPlj_qcQ
- val untyped = resetAttrs(result, leaveAlone = {
+ var importantSymbols = Set[Symbol](
+ NothingClass, AnyClass, SingletonClass, PredefModule, ScalaRunTimeModule, TypeCreatorClass, TreeCreatorClass, MirrorClass,
+ ApiUniverseClass, JavaUniverseClass, ReflectRuntimePackage, runDefinitions.ReflectRuntimeCurrentMirror)
+ importantSymbols ++= importantSymbols map (_.companionSymbol)
+ importantSymbols ++= importantSymbols map (_.moduleClass)
+ importantSymbols ++= importantSymbols map (_.linkedClassOfClass)
+ def isImportantSymbol(sym: Symbol): Boolean = sym != null && sym != NoSymbol && importantSymbols(sym)
+ val untyped = brutallyResetAttrs(result, leaveAlone = {
case ValDef(_, u, _, _) if u == nme.UNIVERSE_SHORT => true
case ValDef(_, m, _, _) if m == nme.MIRROR_SHORT => true
case tree if symtab.syms contains tree.symbol => true
+ case tree if isImportantSymbol(tree.symbol) => true
case _ => false
})
diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala
index d33ea5bb5c..9ca06427e8 100644
--- a/src/compiler/scala/tools/nsc/ast/Trees.scala
+++ b/src/compiler/scala/tools/nsc/ast/Trees.scala
@@ -194,8 +194,18 @@ trait Trees extends scala.reflect.internal.Trees { self: Global =>
//
// def resetAllAttrs(x: Tree, leaveAlone: Tree => Boolean = null): Tree = new ResetAttrs(localOnly = false, leaveAlone).transform(x)
+ // upd. Unfortunately this didn't work out quite as we expected. The last two users of resetAllAttrs:
+ // reification and typedLabelDef broke in very weird ways when we replaced resetAllAttrs with resetLocalAttrs
+ // (see SI-8316 change from resetAllAttrs to resetLocalAttrs in reifiers broke Slick and
+ // SI-8318 NPE in mixin in scala-continuations for more information).
+ // Given that we're supposed to release 2.11.0-RC1 in less than a week, I'm temporarily reinstating resetAllAttrs
+ // until we have time to better understand what's going on. In order to dissuade people from using it,
+ // it now comes with a new, ridiculous name.
/** @see ResetAttrs */
- def resetAttrs(x: Tree, leaveAlone: Tree => Boolean = null): Tree = new ResetAttrs(leaveAlone).transform(x)
+ def brutallyResetAttrs(x: Tree, leaveAlone: Tree => Boolean = null): Tree = new ResetAttrs(brutally = true, leaveAlone).transform(x)
+
+ /** @see ResetAttrs */
+ def resetAttrs(x: Tree): Tree = new ResetAttrs(brutally = false, leaveAlone = null).transform(x)
/** A transformer which resets symbol and tpe fields of all nodes in a given tree,
* with special treatment of:
@@ -206,7 +216,7 @@ trait Trees extends scala.reflect.internal.Trees { self: Global =>
*
* (bq:) This transformer has mutable state and should be discarded after use
*/
- private class ResetAttrs(leaveAlone: Tree => Boolean = null) {
+ private class ResetAttrs(brutally: Boolean, leaveAlone: Tree => Boolean) {
// this used to be based on -Ydebug, but the need for logging in this code is so situational
// that I've reverted to a hard-coded constant here.
val debug = false
@@ -299,7 +309,7 @@ trait Trees extends scala.reflect.internal.Trees { self: Global =>
// if we move these trees into lexical contexts different from their original locations.
if (dupl.hasSymbol) {
val sym = dupl.symbol
- val vetoScope = !(locals contains sym)
+ val vetoScope = !brutally && !(locals contains sym)
val vetoThis = dupl.isInstanceOf[This] && sym.isPackageClass
if (!(vetoScope || vetoThis)) dupl.symbol = NoSymbol
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 8721450dc9..fa96d98bcc 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -2288,7 +2288,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
val sym2 = namer.enterInScope(
context.owner.newLabel(ldef.name, ldef.pos) setInfo MethodType(List(), restpe))
val LabelDef(_, _, rhs1) = resetAttrs(ldef)
- val rhs2 = typed(rhs1, restpe)
+ val rhs2 = typed(brutallyResetAttrs(rhs1), restpe)
ldef.params foreach (param => param setType param.symbol.tpe)
deriveLabelDef(ldef)(_ => rhs2) setSymbol sym2 setType restpe
}
diff --git a/test/files/run/macro-reify-nested-b/Impls_Macros_1.scala b/test/files/run/macro-reify-chained1/Impls_Macros_1.scala
index 3bea04cead..7f877b2729 100644
--- a/test/files/run/macro-reify-nested-b/Impls_Macros_1.scala
+++ b/test/files/run/macro-reify-chained1/Impls_Macros_1.scala
@@ -1,6 +1,7 @@
import scala.reflect.runtime.universe._
import scala.reflect.runtime.{universe => ru}
import scala.reflect.macros.blackbox.Context
+import scala.language.experimental.macros
case class Utils[C <: Context]( c:C ) {
import c.universe._
@@ -34,7 +35,7 @@ object QueryableMacros{
c.universe.reify{ Queryable.factory[S]( foo.splice )}
}
def map[T:c.WeakTypeTag, S:c.WeakTypeTag]
- (c: scala.reflect.macros.blackbox.Context)
+ (c: Context)
(projection: c.Expr[T => S]): c.Expr[Queryable[S]] = _helper[c.type,S]( c )( "_map", projection )
}
class Queryable[T]{
diff --git a/test/files/run/macro-reify-chained1/Test_2.scala b/test/files/run/macro-reify-chained1/Test_2.scala
new file mode 100644
index 0000000000..2adb07b035
--- /dev/null
+++ b/test/files/run/macro-reify-chained1/Test_2.scala
@@ -0,0 +1,9 @@
+object Test extends App{
+ val q : Queryable[Any] = new Queryable[Any]
+ q.map(x => x).map(x => x)
+
+ locally {
+ val q : Queryable[Any] = new Queryable[Any]
+ q.map(x => x).map(x => x)
+ }
+} \ No newline at end of file
diff --git a/test/files/run/macro-reify-chained2/Impls_Macros_1.scala b/test/files/run/macro-reify-chained2/Impls_Macros_1.scala
new file mode 100644
index 0000000000..965b191044
--- /dev/null
+++ b/test/files/run/macro-reify-chained2/Impls_Macros_1.scala
@@ -0,0 +1,47 @@
+import scala.reflect.runtime.universe._
+import scala.reflect.runtime.{universe => ru}
+import scala.reflect.macros.whitebox.Context
+import scala.language.experimental.macros
+
+case class Utils[C <: Context]( c:C ) {
+ import c.universe._
+ import c.{Tree=>_}
+ object removeDoubleReify extends c.universe.Transformer {
+ def apply( tree:Tree ) = transform(tree)
+ override def transform(tree: Tree): Tree = {
+ super.transform {
+ tree match {
+ case Apply(TypeApply(Select(_this, termname), _), reification::Nil )
+ if termname.toString == "factory" => c.unreifyTree(reification)
+ case Apply(Select(_this, termname), reification::Nil )
+ if termname.toString == "factory" => c.unreifyTree(reification)
+ case _ => tree
+ }
+ }
+ }
+ }
+}
+object QueryableMacros{
+ def _helper[C <: Context,S:c.WeakTypeTag]( c:C )( name:String, projection:c.Expr[_] ) = {
+ import c.universe._
+ import internal._
+ val element_type = implicitly[c.WeakTypeTag[S]].tpe
+ val foo = c.Expr[ru.Expr[Queryable[S]]](
+ c.reifyTree( gen.mkRuntimeUniverseRef, EmptyTree, c.typecheck(
+ Utils[c.type](c).removeDoubleReify(
+ Apply(Select(c.prefix.tree, TermName( name )), List( projection.tree ))
+ ).asInstanceOf[Tree]
+ )))
+ c.universe.reify{ Queryable.factory[S]( foo.splice )}
+ }
+ def map[T:c.WeakTypeTag, S:c.WeakTypeTag]
+ (c: Context)
+ (projection: c.Expr[T => S]): c.Expr[Queryable[S]] = _helper[c.type,S]( c )( "_map", projection )
+}
+class Queryable[T]{
+ def _map[S]( projection: T => S ) : Queryable[S] = ???
+ def map[S]( projection: T => S ) : Queryable[S] = macro QueryableMacros.map[T,S]
+}
+object Queryable{
+ def factory[S]( projection:ru.Expr[Queryable[S]] ) : Queryable[S] = null
+} \ No newline at end of file
diff --git a/test/files/run/macro-reify-chained2/Test_2.scala b/test/files/run/macro-reify-chained2/Test_2.scala
new file mode 100644
index 0000000000..2adb07b035
--- /dev/null
+++ b/test/files/run/macro-reify-chained2/Test_2.scala
@@ -0,0 +1,9 @@
+object Test extends App{
+ val q : Queryable[Any] = new Queryable[Any]
+ q.map(x => x).map(x => x)
+
+ locally {
+ val q : Queryable[Any] = new Queryable[Any]
+ q.map(x => x).map(x => x)
+ }
+} \ No newline at end of file
diff --git a/test/files/run/macro-reify-nested-a.flags b/test/files/run/macro-reify-nested-a.flags
deleted file mode 100644
index cd66464f2f..0000000000
--- a/test/files/run/macro-reify-nested-a.flags
+++ /dev/null
@@ -1 +0,0 @@
--language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-reify-nested-a/Impls_Macros_1.scala b/test/files/run/macro-reify-nested-a1/Impls_Macros_1.scala
index 3bea04cead..7f877b2729 100644
--- a/test/files/run/macro-reify-nested-a/Impls_Macros_1.scala
+++ b/test/files/run/macro-reify-nested-a1/Impls_Macros_1.scala
@@ -1,6 +1,7 @@
import scala.reflect.runtime.universe._
import scala.reflect.runtime.{universe => ru}
import scala.reflect.macros.blackbox.Context
+import scala.language.experimental.macros
case class Utils[C <: Context]( c:C ) {
import c.universe._
@@ -34,7 +35,7 @@ object QueryableMacros{
c.universe.reify{ Queryable.factory[S]( foo.splice )}
}
def map[T:c.WeakTypeTag, S:c.WeakTypeTag]
- (c: scala.reflect.macros.blackbox.Context)
+ (c: Context)
(projection: c.Expr[T => S]): c.Expr[Queryable[S]] = _helper[c.type,S]( c )( "_map", projection )
}
class Queryable[T]{
diff --git a/test/files/run/macro-reify-nested-a/Test_2.scala b/test/files/run/macro-reify-nested-a1/Test_2.scala
index fa0eb378af..b99c4c55e4 100644
--- a/test/files/run/macro-reify-nested-a/Test_2.scala
+++ b/test/files/run/macro-reify-nested-a1/Test_2.scala
@@ -1,4 +1,9 @@
object Test extends App{
val q : Queryable[Any] = new Queryable[Any]
q.map(e1 => q.map(e2=>e1))
+
+ locally {
+ val q : Queryable[Any] = new Queryable[Any]
+ q.map(e1 => q.map(e2=>e1))
+ }
} \ No newline at end of file
diff --git a/test/files/run/macro-reify-nested-a2/Impls_Macros_1.scala b/test/files/run/macro-reify-nested-a2/Impls_Macros_1.scala
new file mode 100644
index 0000000000..965b191044
--- /dev/null
+++ b/test/files/run/macro-reify-nested-a2/Impls_Macros_1.scala
@@ -0,0 +1,47 @@
+import scala.reflect.runtime.universe._
+import scala.reflect.runtime.{universe => ru}
+import scala.reflect.macros.whitebox.Context
+import scala.language.experimental.macros
+
+case class Utils[C <: Context]( c:C ) {
+ import c.universe._
+ import c.{Tree=>_}
+ object removeDoubleReify extends c.universe.Transformer {
+ def apply( tree:Tree ) = transform(tree)
+ override def transform(tree: Tree): Tree = {
+ super.transform {
+ tree match {
+ case Apply(TypeApply(Select(_this, termname), _), reification::Nil )
+ if termname.toString == "factory" => c.unreifyTree(reification)
+ case Apply(Select(_this, termname), reification::Nil )
+ if termname.toString == "factory" => c.unreifyTree(reification)
+ case _ => tree
+ }
+ }
+ }
+ }
+}
+object QueryableMacros{
+ def _helper[C <: Context,S:c.WeakTypeTag]( c:C )( name:String, projection:c.Expr[_] ) = {
+ import c.universe._
+ import internal._
+ val element_type = implicitly[c.WeakTypeTag[S]].tpe
+ val foo = c.Expr[ru.Expr[Queryable[S]]](
+ c.reifyTree( gen.mkRuntimeUniverseRef, EmptyTree, c.typecheck(
+ Utils[c.type](c).removeDoubleReify(
+ Apply(Select(c.prefix.tree, TermName( name )), List( projection.tree ))
+ ).asInstanceOf[Tree]
+ )))
+ c.universe.reify{ Queryable.factory[S]( foo.splice )}
+ }
+ def map[T:c.WeakTypeTag, S:c.WeakTypeTag]
+ (c: Context)
+ (projection: c.Expr[T => S]): c.Expr[Queryable[S]] = _helper[c.type,S]( c )( "_map", projection )
+}
+class Queryable[T]{
+ def _map[S]( projection: T => S ) : Queryable[S] = ???
+ def map[S]( projection: T => S ) : Queryable[S] = macro QueryableMacros.map[T,S]
+}
+object Queryable{
+ def factory[S]( projection:ru.Expr[Queryable[S]] ) : Queryable[S] = null
+} \ No newline at end of file
diff --git a/test/files/run/macro-reify-nested-a2/Test_2.scala b/test/files/run/macro-reify-nested-a2/Test_2.scala
new file mode 100644
index 0000000000..b99c4c55e4
--- /dev/null
+++ b/test/files/run/macro-reify-nested-a2/Test_2.scala
@@ -0,0 +1,9 @@
+object Test extends App{
+ val q : Queryable[Any] = new Queryable[Any]
+ q.map(e1 => q.map(e2=>e1))
+
+ locally {
+ val q : Queryable[Any] = new Queryable[Any]
+ q.map(e1 => q.map(e2=>e1))
+ }
+} \ No newline at end of file
diff --git a/test/files/run/macro-reify-nested-b.flags b/test/files/run/macro-reify-nested-b.flags
deleted file mode 100644
index cd66464f2f..0000000000
--- a/test/files/run/macro-reify-nested-b.flags
+++ /dev/null
@@ -1 +0,0 @@
--language:experimental.macros \ No newline at end of file
diff --git a/test/files/run/macro-reify-nested-b1/Impls_Macros_1.scala b/test/files/run/macro-reify-nested-b1/Impls_Macros_1.scala
new file mode 100644
index 0000000000..7f877b2729
--- /dev/null
+++ b/test/files/run/macro-reify-nested-b1/Impls_Macros_1.scala
@@ -0,0 +1,47 @@
+import scala.reflect.runtime.universe._
+import scala.reflect.runtime.{universe => ru}
+import scala.reflect.macros.blackbox.Context
+import scala.language.experimental.macros
+
+case class Utils[C <: Context]( c:C ) {
+ import c.universe._
+ import c.{Tree=>_}
+ object removeDoubleReify extends c.universe.Transformer {
+ def apply( tree:Tree ) = transform(tree)
+ override def transform(tree: Tree): Tree = {
+ super.transform {
+ tree match {
+ case Apply(TypeApply(Select(_this, termname), _), reification::Nil )
+ if termname.toString == "factory" => c.unreifyTree(reification)
+ case Apply(Select(_this, termname), reification::Nil )
+ if termname.toString == "factory" => c.unreifyTree(reification)
+ case _ => tree
+ }
+ }
+ }
+ }
+}
+object QueryableMacros{
+ def _helper[C <: Context,S:c.WeakTypeTag]( c:C )( name:String, projection:c.Expr[_] ) = {
+ import c.universe._
+ import internal._
+ val element_type = implicitly[c.WeakTypeTag[S]].tpe
+ val foo = c.Expr[ru.Expr[Queryable[S]]](
+ c.reifyTree( gen.mkRuntimeUniverseRef, EmptyTree, c.typecheck(
+ Utils[c.type](c).removeDoubleReify(
+ Apply(Select(c.prefix.tree, TermName( name )), List( projection.tree ))
+ ).asInstanceOf[Tree]
+ )))
+ c.universe.reify{ Queryable.factory[S]( foo.splice )}
+ }
+ def map[T:c.WeakTypeTag, S:c.WeakTypeTag]
+ (c: Context)
+ (projection: c.Expr[T => S]): c.Expr[Queryable[S]] = _helper[c.type,S]( c )( "_map", projection )
+}
+class Queryable[T]{
+ def _map[S]( projection: T => S ) : Queryable[S] = ???
+ def map[S]( projection: T => S ) : Queryable[S] = macro QueryableMacros.map[T,S]
+}
+object Queryable{
+ def factory[S]( projection:ru.Expr[Queryable[S]] ) : Queryable[S] = null
+} \ No newline at end of file
diff --git a/test/files/run/macro-reify-nested-b/Test_2.scala b/test/files/run/macro-reify-nested-b1/Test_2.scala
index fa13f57ffb..b199036349 100644
--- a/test/files/run/macro-reify-nested-b/Test_2.scala
+++ b/test/files/run/macro-reify-nested-b1/Test_2.scala
@@ -1,4 +1,9 @@
object Test extends App{
val q : Queryable[Any] = new Queryable[Any]
q.map(e1 => q.map(e2=>e1).map(e2=>e1))
+
+ locally {
+ val q : Queryable[Any] = new Queryable[Any]
+ q.map(e1 => q.map(e2=>e1).map(e2=>e1))
+ }
} \ No newline at end of file
diff --git a/test/files/run/macro-reify-nested-b2/Impls_Macros_1.scala b/test/files/run/macro-reify-nested-b2/Impls_Macros_1.scala
new file mode 100644
index 0000000000..965b191044
--- /dev/null
+++ b/test/files/run/macro-reify-nested-b2/Impls_Macros_1.scala
@@ -0,0 +1,47 @@
+import scala.reflect.runtime.universe._
+import scala.reflect.runtime.{universe => ru}
+import scala.reflect.macros.whitebox.Context
+import scala.language.experimental.macros
+
+case class Utils[C <: Context]( c:C ) {
+ import c.universe._
+ import c.{Tree=>_}
+ object removeDoubleReify extends c.universe.Transformer {
+ def apply( tree:Tree ) = transform(tree)
+ override def transform(tree: Tree): Tree = {
+ super.transform {
+ tree match {
+ case Apply(TypeApply(Select(_this, termname), _), reification::Nil )
+ if termname.toString == "factory" => c.unreifyTree(reification)
+ case Apply(Select(_this, termname), reification::Nil )
+ if termname.toString == "factory" => c.unreifyTree(reification)
+ case _ => tree
+ }
+ }
+ }
+ }
+}
+object QueryableMacros{
+ def _helper[C <: Context,S:c.WeakTypeTag]( c:C )( name:String, projection:c.Expr[_] ) = {
+ import c.universe._
+ import internal._
+ val element_type = implicitly[c.WeakTypeTag[S]].tpe
+ val foo = c.Expr[ru.Expr[Queryable[S]]](
+ c.reifyTree( gen.mkRuntimeUniverseRef, EmptyTree, c.typecheck(
+ Utils[c.type](c).removeDoubleReify(
+ Apply(Select(c.prefix.tree, TermName( name )), List( projection.tree ))
+ ).asInstanceOf[Tree]
+ )))
+ c.universe.reify{ Queryable.factory[S]( foo.splice )}
+ }
+ def map[T:c.WeakTypeTag, S:c.WeakTypeTag]
+ (c: Context)
+ (projection: c.Expr[T => S]): c.Expr[Queryable[S]] = _helper[c.type,S]( c )( "_map", projection )
+}
+class Queryable[T]{
+ def _map[S]( projection: T => S ) : Queryable[S] = ???
+ def map[S]( projection: T => S ) : Queryable[S] = macro QueryableMacros.map[T,S]
+}
+object Queryable{
+ def factory[S]( projection:ru.Expr[Queryable[S]] ) : Queryable[S] = null
+} \ No newline at end of file
diff --git a/test/files/run/macro-reify-nested-b2/Test_2.scala b/test/files/run/macro-reify-nested-b2/Test_2.scala
new file mode 100644
index 0000000000..b199036349
--- /dev/null
+++ b/test/files/run/macro-reify-nested-b2/Test_2.scala
@@ -0,0 +1,9 @@
+object Test extends App{
+ val q : Queryable[Any] = new Queryable[Any]
+ q.map(e1 => q.map(e2=>e1).map(e2=>e1))
+
+ locally {
+ val q : Queryable[Any] = new Queryable[Any]
+ q.map(e1 => q.map(e2=>e1).map(e2=>e1))
+ }
+} \ No newline at end of file