summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bincompat-backward.whitelist.conf8
-rw-r--r--bincompat-forward.whitelist.conf8
-rw-r--r--src/reflect/scala/reflect/internal/BaseTypeSeqs.scala5
-rw-r--r--src/reflect/scala/reflect/runtime/SynchronizedOps.scala11
-rw-r--r--test/files/run/t10026.check1
-rw-r--r--test/files/run/t10026.scala11
6 files changed, 38 insertions, 6 deletions
diff --git a/bincompat-backward.whitelist.conf b/bincompat-backward.whitelist.conf
index 57dc564e8a..9ea78a2977 100644
--- a/bincompat-backward.whitelist.conf
+++ b/bincompat-backward.whitelist.conf
@@ -34,6 +34,14 @@ filter {
problemName=DirectMissingMethodProblem
},
{
+ matchName="scala.reflect.runtime.SynchronizedOps.scala$reflect$runtime$SynchronizedOps$$super$newMappedBaseTypeSeq"
+ problemName=ReversedMissingMethodProblem
+ },
+ {
+ matchName="scala.reflect.runtime.SynchronizedOps#SynchronizedBaseTypeSeq.lateMap"
+ problemName=DirectMissingMethodProblem
+ },
+ {
matchName="scala.collection.immutable.HashMap.contains0"
problemName=DirectMissingMethodProblem
},
diff --git a/bincompat-forward.whitelist.conf b/bincompat-forward.whitelist.conf
index ad778f447a..b765fb384b 100644
--- a/bincompat-forward.whitelist.conf
+++ b/bincompat-forward.whitelist.conf
@@ -44,6 +44,14 @@ filter {
problemName=DirectMissingMethodProblem
},
{
+ matchName="scala.reflect.runtime.SynchronizedOps.newMappedBaseTypeSeq"
+ problemName=DirectMissingMethodProblem
+ },
+ {
+ matchName="scala.reflect.runtime.JavaUniverse.newMappedBaseTypeSeq"
+ problemName=DirectMissingMethodProblem
+ },
+ {
matchName="scala.collection.immutable.HashMap.contains0"
problemName=DirectMissingMethodProblem
},
diff --git a/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala b/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala
index 0ef52213e5..1cdefff2e9 100644
--- a/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala
+++ b/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala
@@ -33,6 +33,9 @@ trait BaseTypeSeqs {
protected def newBaseTypeSeq(parents: List[Type], elems: Array[Type]) =
new BaseTypeSeq(parents, elems)
+ protected def newMappedBaseTypeSeq(orig: BaseTypeSeq, f: Type => Type) =
+ new MappedBaseTypeSeq(orig, f)
+
/** Note: constructor is protected to force everyone to use the factory method newBaseTypeSeq instead.
* This is necessary because when run from reflection every base type sequence needs to have a
* SynchronizedBaseTypeSeq as mixin.
@@ -125,7 +128,7 @@ trait BaseTypeSeqs {
newBaseTypeSeq(parents, arr)
}
- def lateMap(f: Type => Type): BaseTypeSeq = new MappedBaseTypeSeq(this, f)
+ def lateMap(f: Type => Type): BaseTypeSeq = newMappedBaseTypeSeq(this, f)
def exists(p: Type => Boolean): Boolean = elems exists p
diff --git a/src/reflect/scala/reflect/runtime/SynchronizedOps.scala b/src/reflect/scala/reflect/runtime/SynchronizedOps.scala
index f0d96e0fd6..eadafc8abb 100644
--- a/src/reflect/scala/reflect/runtime/SynchronizedOps.scala
+++ b/src/reflect/scala/reflect/runtime/SynchronizedOps.scala
@@ -18,6 +18,12 @@ private[reflect] trait SynchronizedOps extends internal.SymbolTable
if (elems.exists(_.isInstanceOf[RefinedType])) new BaseTypeSeq(parents, elems) with SynchronizedBaseTypeSeq
else new BaseTypeSeq(parents, elems)
+ override protected def newMappedBaseTypeSeq(orig: BaseTypeSeq, f: Type => Type) =
+ // MappedBaseTypeSeq's are used rarely enough that we unconditionally mixin the synchronized
+ // wrapper, rather than doing this conditionally. A previous attempt to do that broke the "late"
+ // part of the "lateMap" contract in inspecting the mapped elements.
+ new MappedBaseTypeSeq(orig, f) with SynchronizedBaseTypeSeq
+
trait SynchronizedBaseTypeSeq extends BaseTypeSeq {
override def apply(i: Int): Type = gilSynchronized { super.apply(i) }
override def rawElem(i: Int) = gilSynchronized { super.rawElem(i) }
@@ -28,11 +34,6 @@ private[reflect] trait SynchronizedOps extends internal.SymbolTable
override def exists(p: Type => Boolean): Boolean = gilSynchronized { super.exists(p) }
override lazy val maxDepth = gilSynchronized { maxDepthOfElems }
override def toString = gilSynchronized { super.toString }
-
- override def lateMap(f: Type => Type): BaseTypeSeq =
- // only need to synchronize BaseTypeSeqs if they contain refined types
- if (map(f).toList.exists(_.isInstanceOf[RefinedType])) new MappedBaseTypeSeq(this, f) with SynchronizedBaseTypeSeq
- else new MappedBaseTypeSeq(this, f)
}
// Scopes
diff --git a/test/files/run/t10026.check b/test/files/run/t10026.check
new file mode 100644
index 0000000000..15a62794a9
--- /dev/null
+++ b/test/files/run/t10026.check
@@ -0,0 +1 @@
+List(1, 2, 3)
diff --git a/test/files/run/t10026.scala b/test/files/run/t10026.scala
new file mode 100644
index 0000000000..a56840c8c2
--- /dev/null
+++ b/test/files/run/t10026.scala
@@ -0,0 +1,11 @@
+import scala.reflect.runtime.universe
+import scala.tools.reflect.ToolBox
+
+object Test {
+ def main(args: Array[String]): Unit = {
+ val classloader = getClass.getClassLoader
+ val toolbox = universe.runtimeMirror(classloader).mkToolBox()
+ println(toolbox.compile(toolbox.parse("Array(1, 2, 3).toList")).apply())
+ }
+}
+