summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2013-08-17 16:23:02 +0200
committerJason Zaugg <jzaugg@gmail.com>2013-08-17 16:42:58 +0200
commitd877d0cb32a1198d7b40fe0c4583b6f4f488dc52 (patch)
tree5a3eee765639e8a00414f995c41b57868b242a25
parent5084b74048f7f21f38fdf45ebfa8e634b863bb01 (diff)
downloadscala-d877d0cb32a1198d7b40fe0c4583b6f4f488dc52.tar.gz
scala-d877d0cb32a1198d7b40fe0c4583b6f4f488dc52.tar.bz2
scala-d877d0cb32a1198d7b40fe0c4583b6f4f488dc52.zip
SI-7501 Pickler: owner adjustment for param syms in annotation args
Pickling of trees within annotation arguments led to an unfortunate situation: the MethodType of a symbol contained a value parameter symbol that was pickled as though it were owned by the enclosing class (the root symbol of the pickle.) Under separate compilation, this would appear as a member of that class. Anyone using `@deprecatedName('oldName)` was exposed to this problem, as the argument expands to `Symbol.apply("oldName")`. This commit extends some similar treatment of local type parameters to also consider value parameters.
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala7
-rw-r--r--test/files/neg/t7501.check7
-rw-r--r--test/files/neg/t7501/t7501_1.scala12
-rw-r--r--test/files/neg/t7501/t7501_2.scala5
4 files changed, 30 insertions, 1 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala
index 9bad29097c..9ac1ce1b9c 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala
@@ -88,12 +88,17 @@ abstract class Pickler extends SubComponent {
/** Returns usually symbol's owner, but picks classfile root instead
* for existentially bound variables that have a non-local owner.
* Question: Should this be done for refinement class symbols as well?
+ *
+ * Note: tree pickling also finds its way here; e.g. in SI-7501 the pickling
+ * of trees in annotation arguments considers the parameter symbol of a method
+ * called in such a tree as "local". The condition `sym.isValueParameter` was
+ * added to fix that bug, but there may be a better way.
*/
private def localizedOwner(sym: Symbol) =
if (isLocal(sym) && !isRootSym(sym) && !isLocal(sym.owner))
// don't use a class as the localized owner for type parameters that are not owned by a class: those are not instantiated by asSeenFrom
// however, they would suddenly be considered by asSeenFrom if their localized owner became a class (causing the crashes of #4079, #2741)
- (if(sym.isTypeParameter && !sym.owner.isClass) nonClassRoot
+ (if ((sym.isTypeParameter || sym.isValueParameter) && !sym.owner.isClass) nonClassRoot
else root)
else sym.owner
diff --git a/test/files/neg/t7501.check b/test/files/neg/t7501.check
new file mode 100644
index 0000000000..2ded07c7ed
--- /dev/null
+++ b/test/files/neg/t7501.check
@@ -0,0 +1,7 @@
+t7501_2.scala:2: error: value name is not a member of A
+ def foo(a: A) = a.name
+ ^
+t7501_2.scala:4: error: not found: type X
+ type TP = X // already failed before this fix
+ ^
+two errors found
diff --git a/test/files/neg/t7501/t7501_1.scala b/test/files/neg/t7501/t7501_1.scala
new file mode 100644
index 0000000000..323c327623
--- /dev/null
+++ b/test/files/neg/t7501/t7501_1.scala
@@ -0,0 +1,12 @@
+object Test2 {
+ def test[X](name: String) = 12
+}
+class strangeTest(x: Int) extends scala.annotation.StaticAnnotation
+
+trait A {
+ // When picking the type of `test`, the value parameter
+ // `x` was pickled with the owner `trait A`. On unpickling,
+ // it was taken to be a member!
+ @strangeTest(Test2.test("test"))
+ def test(x: String): Unit
+}
diff --git a/test/files/neg/t7501/t7501_2.scala b/test/files/neg/t7501/t7501_2.scala
new file mode 100644
index 0000000000..044caea3c3
--- /dev/null
+++ b/test/files/neg/t7501/t7501_2.scala
@@ -0,0 +1,5 @@
+object Test {
+ def foo(a: A) = a.name
+
+ type TP = X // already failed before this fix
+}