summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bincompat-forward.whitelist.conf5
-rw-r--r--build.number2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala2
-rw-r--r--src/reflect/scala/reflect/runtime/JavaMirrors.scala11
-rw-r--r--test/files/run/macro-vampire-false-warning.check2
-rw-r--r--test/files/run/macro-vampire-false-warning.flags1
-rw-r--r--test/files/run/macro-vampire-false-warning/Macros_1.scala52
-rw-r--r--test/files/run/macro-vampire-false-warning/Test_2.scala6
-rw-r--r--test/files/run/t8196.check3
-rw-r--r--test/files/run/t8196.scala51
10 files changed, 129 insertions, 6 deletions
diff --git a/bincompat-forward.whitelist.conf b/bincompat-forward.whitelist.conf
index 087fa07b37..7879ecfd84 100644
--- a/bincompat-forward.whitelist.conf
+++ b/bincompat-forward.whitelist.conf
@@ -173,6 +173,11 @@ filter {
{
matchName="scala.reflect.runtime.SymbolLoaders.isInvalidClassName"
problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.reflect.runtime.JavaMirrors#JavaMirror.scala$reflect$runtime$JavaMirrors$JavaMirror$$followStatic"
+ problemName=MissingMethodProblem
}
+
]
}
diff --git a/build.number b/build.number
index 7c027e7797..de2c2fb824 100644
--- a/build.number
+++ b/build.number
@@ -1,7 +1,7 @@
#Tue Sep 11 19:21:09 CEST 2007
version.major=2
version.minor=10
-version.patch=4
+version.patch=5
# This is the -N part of a version. if it's 0, it's dropped from maven versions.
version.bnum=0
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index e09a509839..8153766784 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -4934,7 +4934,7 @@ trait Typers extends Modes with Adaptations with Tags {
if (tree.isInstanceOf[PostfixSelect])
checkFeature(tree.pos, PostfixOpsFeature, name.decode)
- if (tree1.symbol != null && tree1.symbol.isOnlyRefinementMember)
+ if (tree1.symbol != null && tree1.symbol.isOnlyRefinementMember && !tree1.symbol.isMacro)
checkFeature(tree1.pos, ReflectiveCallsFeature, tree1.symbol.toString)
if (qual1.hasSymbolWhich(_.isRootPackage)) treeCopy.Ident(tree1, name)
diff --git a/src/reflect/scala/reflect/runtime/JavaMirrors.scala b/src/reflect/scala/reflect/runtime/JavaMirrors.scala
index 6fdb238462..9c0781ca06 100644
--- a/src/reflect/scala/reflect/runtime/JavaMirrors.scala
+++ b/src/reflect/scala/reflect/runtime/JavaMirrors.scala
@@ -685,8 +685,7 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni
module.moduleClass setInfo new ClassInfoType(List(), newScope, module.moduleClass)
}
- def enter(sym: Symbol, mods: Int) =
- (if (jModifier.isStatic(mods)) module.moduleClass else clazz).info.decls enter sym
+ def enter(sym: Symbol, mods: Int) = followStatic(clazz, module, mods).info.decls enter sym
def enterEmptyCtorIfNecessary(): Unit = {
if (jclazz.getConstructors.isEmpty)
@@ -733,8 +732,12 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni
* If Java modifiers `mods` contain STATIC, return the module class
* of the companion module of `clazz`, otherwise the class `clazz` itself.
*/
- private def followStatic(clazz: Symbol, mods: Int) =
- if (jModifier.isStatic(mods)) clazz.companionModule.moduleClass else clazz
+ private def followStatic(clazz: Symbol, mods: Int): Symbol = followStatic(clazz, clazz.companionModule, mods)
+
+ private def followStatic(clazz: Symbol, module: Symbol, mods: Int): Symbol =
+ // SI-8196 `orElse(clazz)` needed for implementation details of the backend, such as the static
+ // field containing the cache for structural calls.
+ if (jModifier.isStatic(mods)) module.moduleClass.orElse(clazz) else clazz
/** Methods which need to be treated with care
* because they either are getSimpleName or call getSimpleName:
diff --git a/test/files/run/macro-vampire-false-warning.check b/test/files/run/macro-vampire-false-warning.check
new file mode 100644
index 0000000000..4792e70f33
--- /dev/null
+++ b/test/files/run/macro-vampire-false-warning.check
@@ -0,0 +1,2 @@
+2
+3
diff --git a/test/files/run/macro-vampire-false-warning.flags b/test/files/run/macro-vampire-false-warning.flags
new file mode 100644
index 0000000000..e8fb65d50c
--- /dev/null
+++ b/test/files/run/macro-vampire-false-warning.flags
@@ -0,0 +1 @@
+-Xfatal-warnings \ No newline at end of file
diff --git a/test/files/run/macro-vampire-false-warning/Macros_1.scala b/test/files/run/macro-vampire-false-warning/Macros_1.scala
new file mode 100644
index 0000000000..a1c40a5510
--- /dev/null
+++ b/test/files/run/macro-vampire-false-warning/Macros_1.scala
@@ -0,0 +1,52 @@
+// As per http://meta.plasm.us/posts/2013/08/31/feeding-our-vampires/
+
+import scala.annotation.StaticAnnotation
+import scala.reflect.macros.Context
+import scala.language.experimental.macros
+
+class body(tree: Any) extends StaticAnnotation
+
+object Macros {
+ def selFieldImpl(c: Context) = {
+ import c.universe._
+ val field = c.macroApplication.symbol
+ val bodyAnn = field.annotations.filter(_.tpe <:< typeOf[body]).head
+ c.Expr[Any](bodyAnn.scalaArgs.head)
+ }
+
+ def mkObjectImpl(c: Context)(xs: c.Expr[Any]*) = {
+ import c.universe._
+ import Flag._
+ // val kvps = xs.toList map { case q"${_}(${Literal(Constant(name: String))}).->[${_}]($value)" => name -> value }
+ val kvps = xs.map(_.tree).toList map { case Apply(TypeApply(Select(Apply(_, List(Literal(Constant(name: String)))), _), _), List(value)) => name -> value }
+ // val fields = kvps map { case (k, v) => q"@body($v) def ${TermName(k)} = macro Macros.selFieldImpl" }
+ val fields = kvps map { case (k, v) => DefDef(
+ Modifiers(MACRO, tpnme.EMPTY, List(Apply(Select(New(Ident(newTypeName("body"))), nme.CONSTRUCTOR), List(v)))),
+ newTermName(k), Nil, Nil, TypeTree(), Select(Ident(newTermName("Macros")), newTermName("selFieldImpl"))) }
+ // q"import scala.language.experimental.macros; class Workaround { ..$fields }; new Workaround{}"
+ c.Expr[Any](Block(
+ List(
+ Import(Select(Select(Ident(newTermName("scala")), newTermName("language")), newTermName("experimental")), List(ImportSelector(newTermName("macros"), 51, newTermName("macros"), 51))),
+ ClassDef(
+ NoMods, newTypeName("Workaround"), Nil,
+ Template(
+ List(Select(Ident(newTermName("scala")), newTypeName("AnyRef"))), emptyValDef,
+ DefDef(
+ NoMods, nme.CONSTRUCTOR, Nil, List(Nil), TypeTree(),
+ Block(List(Apply(Select(Super(This(tpnme.EMPTY), tpnme.EMPTY), nme.CONSTRUCTOR), List())), Literal(Constant(()))))
+ +: fields)),
+ ClassDef(
+ Modifiers(FINAL), newTypeName("$anon"), Nil,
+ Template(
+ List(Ident(newTypeName("Workaround"))), emptyValDef,
+ List(
+ DefDef(
+ NoMods, nme.CONSTRUCTOR, Nil, List(Nil), TypeTree(),
+ Block(List(Apply(Select(Super(This(tpnme.EMPTY), tpnme.EMPTY), nme.CONSTRUCTOR), List())), Literal(Constant(())))))))),
+ Apply(Select(New(Ident(newTypeName("$anon"))), nme.CONSTRUCTOR), List())))
+ }
+}
+
+object mkObject {
+ def apply(xs: Any*) = macro Macros.mkObjectImpl
+}
diff --git a/test/files/run/macro-vampire-false-warning/Test_2.scala b/test/files/run/macro-vampire-false-warning/Test_2.scala
new file mode 100644
index 0000000000..6e44b68635
--- /dev/null
+++ b/test/files/run/macro-vampire-false-warning/Test_2.scala
@@ -0,0 +1,6 @@
+object Test extends App {
+ val foo = mkObject("x" -> "2", "y" -> 3)
+ println(foo.x)
+ println(foo.y)
+ // println(foo.z) => will result in a compilation error
+} \ No newline at end of file
diff --git a/test/files/run/t8196.check b/test/files/run/t8196.check
new file mode 100644
index 0000000000..3286c15c91
--- /dev/null
+++ b/test/files/run/t8196.check
@@ -0,0 +1,3 @@
+Scope{
+ final private val f1: Int
+}
diff --git a/test/files/run/t8196.scala b/test/files/run/t8196.scala
new file mode 100644
index 0000000000..e219ac166b
--- /dev/null
+++ b/test/files/run/t8196.scala
@@ -0,0 +1,51 @@
+import scala.reflect.runtime.{ universe => ru }
+
+object Test extends App {
+
+ trait FormTrait {
+
+ val runtimeMirror = ru.runtimeMirror(this.getClass.getClassLoader)
+ val instanceMirror = runtimeMirror.reflect(this)
+ val members = instanceMirror.symbol.typeSignature.members
+ def fields = members.filter(_.typeSignature <:< ru.typeOf[Int])
+ }
+
+ val f = () => {
+
+ class Form1 extends FormTrait {
+ val f1 = 5
+ }
+ val form1 = new Form1
+
+ println(form1.fields)
+
+ val form2 = new FormTrait {
+ val g1 = new Form1
+ }
+
+ form2.g1 // comment this line in order to make the test pass
+ ()
+ }
+
+ val g = () => {
+ // Reported as SI-8195, same root cause
+ trait Form {
+
+ private val runtimeMirror = ru.runtimeMirror(this.getClass.getClassLoader)
+ private val instanceMirror = runtimeMirror.reflect(this)
+ private val members = instanceMirror.symbol.typeSignature.members
+
+ }
+
+ val f1 = new Form {
+ val a = 1
+ }
+
+ val f2 = new Form {
+ val b = f1.a
+ }
+ }
+
+ f()
+ g()
+}