summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'dev-lang/scala/files/scala-2.10.2-jdk-1.7-swing-SI-7455.patch')
-rw-r--r--dev-lang/scala/files/scala-2.10.2-jdk-1.7-swing-SI-7455.patch165
1 files changed, 165 insertions, 0 deletions
diff --git a/dev-lang/scala/files/scala-2.10.2-jdk-1.7-swing-SI-7455.patch b/dev-lang/scala/files/scala-2.10.2-jdk-1.7-swing-SI-7455.patch
new file mode 100644
index 000000000000..964b323d9b30
--- /dev/null
+++ b/dev-lang/scala/files/scala-2.10.2-jdk-1.7-swing-SI-7455.patch
@@ -0,0 +1,165 @@
+commit f3f1064c90371449949892f30de91cc1f2662c55
+Merge: 0b7dddb 050b4c9
+Author: Grzegorz Kossakowski <grzegorz.kossakowski@gmail.com>
+Date: Sat Jul 27 22:39:44 2013 -0700
+
+ Merge pull request #2750 from retronym/ticket/7455-2.10.x
+
+ SI-7455 Drop dummy param for synthetic access constructor
+
+commit 050b4c951c838699c2fe30cbf01b63942c63a299
+Author: Jason Zaugg <jzaugg@gmail.com>
+Date: Wed Jul 17 15:52:48 2013 +1000
+
+ SI-7455 Drop dummy param for synthetic access constructor
+
+ Java synthesizes public constructors in private classes to
+ allow access from inner classes. The signature of
+ that synthetic constructor (known as a "access constructor")
+ has a dummy parameter appended to avoid overloading clashes.
+ javac chooses the type "Enclosing$1" for the dummy parameter
+ (called the "access constructor tag") which is either an
+ existing anonymous class or a synthesized class for this purpose.
+
+ In OpenJDK, this transformation is performed in:
+
+ langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java
+
+ (Incidentally, scalac would just emits a byte-code public
+ constructor in this situation, rather than a private constructor /
+ access constructor pair.)
+
+ Scala parses the signature of the access contructor, and drops
+ the $outer parameter, but retains the dummy parameter. This causes
+ havoc when it tries to parse the bytecode for that anonymous class;
+ the class file parser doesn't have the enclosing type parameters
+ of Vector in scope and crash ensues.
+
+ In any case, we shouldn't allow user code to see that constructor;
+ it should only be called from within its own compilation unit.
+
+ This commit drops the dummy parameter from access constructor
+ signatures in class file parsing.
+
+diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
+index da11754..4e5204f 100644
+--- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
++++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
+@@ -626,7 +626,7 @@ abstract class ClassfileParser {
+ sawPrivateConstructor = true
+ in.skip(2); skipAttributes()
+ } else {
+- if ((sflags & PRIVATE) != 0L && global.settings.optimise.value) {
++ if ((sflags & PRIVATE) != 0L && global.settings.optimise.value) { // TODO this should be !optimize, no? See c4181f656d.
+ in.skip(4); skipAttributes()
+ } else {
+ val name = pool.getName(in.nextChar)
+@@ -636,7 +636,7 @@ abstract class ClassfileParser {
+ info match {
+ case MethodType(params, restpe) =>
+ // if this is a non-static inner class, remove the explicit outer parameter
+- val newParams = innerClasses getEntry currentClass match {
++ val paramsNoOuter = innerClasses getEntry currentClass match {
+ case Some(entry) if !isScalaRaw && !isStatic(entry.jflags) =>
+ /* About `clazz.owner.isPackage` below: SI-5957
+ * For every nested java class A$B, there are two symbols in the scala compiler.
+@@ -650,6 +650,15 @@ abstract class ClassfileParser {
+ case _ =>
+ params
+ }
++ val newParams = paramsNoOuter match {
++ case (init :+ tail) if (jflags & JAVA_ACC_SYNTHETIC) != 0L =>
++ // SI-7455 strip trailing dummy argument ("access constructor tag") from synthetic constructors which
++ // are added when an inner class needs to access a private constructor.
++ init
++ case _ =>
++ paramsNoOuter
++ }
++
+ info = MethodType(newParams, clazz.tpe)
+ }
+ sym.setInfo(info)
+diff --git a/test/files/run/t7455.check b/test/files/run/t7455.check
+new file mode 100644
+index 0000000..0eb9342
+--- /dev/null
++++ b/test/files/run/t7455.check
+@@ -0,0 +1,4 @@
++private[package <empty>] def <init>(x$1: String): Outer[E]
++private[package <empty>] def <init>(): Outer$PrivateInner
++private[package <empty>] def <init>(): Outer$PrivateStaticInner
++private[package <empty>] def <init>(x$2: String): Outer$PublicInner
+diff --git a/test/files/run/t7455/Outer.java b/test/files/run/t7455/Outer.java
+new file mode 100644
+index 0000000..10c97a9
+--- /dev/null
++++ b/test/files/run/t7455/Outer.java
+@@ -0,0 +1,31 @@
++public class Outer<E> {
++ public void elements() {
++ new C<E>() {
++ };
++ }
++
++ private Outer(String a) {}
++
++ static class SubSelf extends Outer<String> {
++ public SubSelf() { super(""); }
++ }
++
++ private class PrivateInner {
++ }
++ class SubPrivateInner extends PrivateInner {
++ }
++
++ private class PublicInner {
++ private PublicInner(String a) {}
++ }
++ class SubPublicInner extends PublicInner {
++ public SubPublicInner() { super(""); }
++ }
++
++ private static class PrivateStaticInner {
++ }
++ public static class SubPrivateStaticInner extends PrivateStaticInner {
++ }
++}
++
++class C<E> {}
+diff --git a/test/files/run/t7455/Test.scala b/test/files/run/t7455/Test.scala
+new file mode 100644
+index 0000000..b23a724
+--- /dev/null
++++ b/test/files/run/t7455/Test.scala
+@@ -0,0 +1,30 @@
++import scala.tools.partest._
++
++// javac adds dummy parameters of type Outer$1 to synthetic access constructors
++// This test shows that we strip them from the signatures. If we don't, we trigger
++// parsing of Outer$1 which can fail if it references type parameters of the Outer.
++//
++// OLD OUTPUT:
++// private[package <empty>] def <init>(x$2: Outer$1): Outer$PrivateInner
++// error: error while loading Outer$1, class file 't7455-run.obj/Outer$1.class' is broken
++// (class java.util.NoSuchElementException/key not found: E)
++// ...
++object Test extends DirectTest {
++ override def code = ""
++
++ def show {
++ val classpath = List(sys.props("partest.lib"), testOutput.path) mkString sys.props("path.separator")
++ val compiler = newCompiler("-cp", classpath, "-d", testOutput.path)
++ import compiler._, definitions._
++ new compiler.Run
++
++ for {
++ name <- Seq("Outer", "Outer$PrivateInner", "Outer$PrivateStaticInner", "Outer$PublicInner")
++ clazz = compiler.rootMirror.staticClass(name)
++ constr <- clazz.info.member(nme.CONSTRUCTOR).alternatives
++ } {
++ println(constr.defString)
++ fullyInitializeSymbol(constr)
++ }
++ }
++}
+