summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bincompat-backward.whitelist.conf99
-rw-r--r--bincompat-forward.whitelist.conf101
-rw-r--r--src/compiler/scala/tools/nsc/ast/Trees.scala3
-rw-r--r--src/library/scala/PartialFunction.scala2
-rw-r--r--src/library/scala/collection/mutable/ArrayOps.scala19
-rw-r--r--test/files/neg/t8372.check7
-rw-r--r--test/files/neg/t8372.scala10
-rw-r--r--test/files/pos/t8369a.check0
-rw-r--r--test/files/pos/t8369a.scala5
-rw-r--r--test/files/pos/t8369b.check0
-rw-r--r--test/files/pos/t8369b.scala18
11 files changed, 259 insertions, 5 deletions
diff --git a/bincompat-backward.whitelist.conf b/bincompat-backward.whitelist.conf
index 9e93c32c70..10c1da59b8 100644
--- a/bincompat-backward.whitelist.conf
+++ b/bincompat-backward.whitelist.conf
@@ -4,4 +4,103 @@ filter {
# "scala.concurrent.impl"
# "scala.reflect.runtime"
]
+ // see SI-8372
+ problems=[
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofChar.unzip"
+ problemName=IncompatibleMethTypeProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofChar.unzip3"
+ problemName=IncompatibleMethTypeProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofByte.unzip"
+ problemName=IncompatibleMethTypeProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofByte.unzip3"
+ problemName=IncompatibleMethTypeProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofShort.unzip"
+ problemName=IncompatibleMethTypeProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofShort.unzip3"
+ problemName=IncompatibleMethTypeProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofLong.unzip"
+ problemName=IncompatibleMethTypeProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofLong.unzip3"
+ problemName=IncompatibleMethTypeProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofInt.unzip"
+ problemName=IncompatibleMethTypeProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofInt.unzip3"
+ problemName=IncompatibleMethTypeProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps.unzip"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps.unzip3"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps.unzip"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps.unzip3"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofFloat.unzip"
+ problemName=IncompatibleMethTypeProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofFloat.unzip3"
+ problemName=IncompatibleMethTypeProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofBoolean.unzip"
+ problemName=IncompatibleMethTypeProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofBoolean.unzip3"
+ problemName=IncompatibleMethTypeProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofRef.unzip"
+ problemName=IncompatibleMethTypeProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofRef.unzip3"
+ problemName=IncompatibleMethTypeProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofUnit.unzip"
+ problemName=IncompatibleMethTypeProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofUnit.unzip3"
+ problemName=IncompatibleMethTypeProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofDouble.unzip"
+ problemName=IncompatibleMethTypeProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofDouble.unzip3"
+ problemName=IncompatibleMethTypeProblem
+ }
+ ]
} \ No newline at end of file
diff --git a/bincompat-forward.whitelist.conf b/bincompat-forward.whitelist.conf
index 9e93c32c70..96994f8969 100644
--- a/bincompat-forward.whitelist.conf
+++ b/bincompat-forward.whitelist.conf
@@ -4,4 +4,103 @@ filter {
# "scala.concurrent.impl"
# "scala.reflect.runtime"
]
-} \ No newline at end of file
+ // see SI-8372
+ problems=[
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofChar.unzip"
+ problemName=IncompatibleMethTypeProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofChar.unzip3"
+ problemName=IncompatibleMethTypeProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofByte.unzip"
+ problemName=IncompatibleMethTypeProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofByte.unzip3"
+ problemName=IncompatibleMethTypeProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofShort.unzip"
+ problemName=IncompatibleMethTypeProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofShort.unzip3"
+ problemName=IncompatibleMethTypeProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofLong.unzip"
+ problemName=IncompatibleMethTypeProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofLong.unzip3"
+ problemName=IncompatibleMethTypeProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofInt.unzip"
+ problemName=IncompatibleMethTypeProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofInt.unzip3"
+ problemName=IncompatibleMethTypeProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps.unzip"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps.unzip3"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps.unzip"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps.unzip3"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofFloat.unzip"
+ problemName=IncompatibleMethTypeProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofFloat.unzip3"
+ problemName=IncompatibleMethTypeProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofBoolean.unzip"
+ problemName=IncompatibleMethTypeProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofBoolean.unzip3"
+ problemName=IncompatibleMethTypeProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofRef.unzip"
+ problemName=IncompatibleMethTypeProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofRef.unzip3"
+ problemName=IncompatibleMethTypeProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofUnit.unzip"
+ problemName=IncompatibleMethTypeProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofUnit.unzip3"
+ problemName=IncompatibleMethTypeProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofDouble.unzip"
+ problemName=IncompatibleMethTypeProblem
+ },
+ {
+ matchName="scala.collection.mutable.ArrayOps#ofDouble.unzip3"
+ problemName=IncompatibleMethTypeProblem
+ }
+ ]
+}
diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala
index 9ca06427e8..3652f51153 100644
--- a/src/compiler/scala/tools/nsc/ast/Trees.scala
+++ b/src/compiler/scala/tools/nsc/ast/Trees.scala
@@ -240,6 +240,7 @@ trait Trees extends scala.reflect.internal.Trees { self: Global =>
registerLocal(sym.moduleClass)
registerLocal(sym.companionClass)
registerLocal(sym.companionModule)
+ registerLocal(sym.deSkolemize)
sym match {
case sym: TermSymbol => registerLocal(sym.referenced)
case _ => ;
@@ -309,7 +310,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 = !brutally && !(locals contains sym)
+ val vetoScope = !brutally && !(locals contains sym) && !(locals contains sym.deSkolemize)
val vetoThis = dupl.isInstanceOf[This] && sym.isPackageClass
if (!(vetoScope || vetoThis)) dupl.symbol = NoSymbol
}
diff --git a/src/library/scala/PartialFunction.scala b/src/library/scala/PartialFunction.scala
index 9ff648a05a..7f4a9dc45d 100644
--- a/src/library/scala/PartialFunction.scala
+++ b/src/library/scala/PartialFunction.scala
@@ -94,7 +94,7 @@ trait PartialFunction[-A, +B] extends (A => B) { self =>
* Note that expression `pf.applyOrElse(x, default)` is equivalent to
* {{{ if(pf isDefinedAt x) pf(x) else default(x) }}}
* except that `applyOrElse` method can be implemented more efficiently.
- * For all partial function literals compiler generates `applyOrElse` implementation which
+ * For all partial function literals the compiler generates an `applyOrElse` implementation which
* avoids double evaluation of pattern matchers and guards.
* This makes `applyOrElse` the basis for the efficient implementation for many operations and scenarios, such as:
*
diff --git a/src/library/scala/collection/mutable/ArrayOps.scala b/src/library/scala/collection/mutable/ArrayOps.scala
index e342e134b4..00491ef20e 100644
--- a/src/library/scala/collection/mutable/ArrayOps.scala
+++ b/src/library/scala/collection/mutable/ArrayOps.scala
@@ -114,10 +114,16 @@ trait ArrayOps[T] extends Any with ArrayLike[T, Array[T]] with CustomParalleliza
* @tparam T2 the type of the second half of the element pairs
* @param asPair an implicit conversion which asserts that the element type
* of this Array is a pair.
+ * @param ct1 a class tag for T1 type parameter that is required to create an instance
+ * of Array[T1]
+ * @param ct2 a class tag for T2 type parameter that is required to create an instance
+ * of Array[T2]
* @return a pair of Arrays, containing, respectively, the first and second half
* of each element pair of this Array.
*/
- def unzip[T1: ClassTag, T2: ClassTag](implicit asPair: T => (T1, T2)): (Array[T1], Array[T2]) = {
+ // implementation NOTE: ct1 and ct2 can't be written as context bounds because desugared
+ // implicits are put in front of asPair parameter that is supposed to guide type inference
+ def unzip[T1, T2](implicit asPair: T => (T1, T2), ct1: ClassTag[T1], ct2: ClassTag[T2]): (Array[T1], Array[T2]) = {
val a1 = new Array[T1](length)
val a2 = new Array[T2](length)
var i = 0
@@ -137,10 +143,19 @@ trait ArrayOps[T] extends Any with ArrayLike[T, Array[T]] with CustomParalleliza
* @tparam T3 the type of the third of three elements in the triple
* @param asTriple an implicit conversion which asserts that the element type
* of this Array is a triple.
+ * @param ct1 a class tag for T1 type parameter that is required to create an instance
+ * of Array[T1]
+ * @param ct2 a class tag for T2 type parameter that is required to create an instance
+ * of Array[T2]
+ * @param ct3 a class tag for T3 type parameter that is required to create an instance
+ * of Array[T3]
* @return a triple of Arrays, containing, respectively, the first, second, and third
* elements from each element triple of this Array.
*/
- def unzip3[T1: ClassTag, T2: ClassTag, T3: ClassTag](implicit asTriple: T => (T1, T2, T3)): (Array[T1], Array[T2], Array[T3]) = {
+ // implementation NOTE: ct1, ct2, ct3 can't be written as context bounds because desugared
+ // implicits are put in front of asPair parameter that is supposed to guide type inference
+ def unzip3[T1, T2, T3](implicit asTriple: T => (T1, T2, T3), ct1: ClassTag[T1], ct2: ClassTag[T2],
+ ct3: ClassTag[T3]): (Array[T1], Array[T2], Array[T3]) = {
val a1 = new Array[T1](length)
val a2 = new Array[T2](length)
val a3 = new Array[T3](length)
diff --git a/test/files/neg/t8372.check b/test/files/neg/t8372.check
new file mode 100644
index 0000000000..6a6424a834
--- /dev/null
+++ b/test/files/neg/t8372.check
@@ -0,0 +1,7 @@
+t8372.scala:7: error: No ClassTag available for T1
+ def unzip[T1, T2](a: Array[(T1, T2)]) = a.unzip
+ ^
+t8372.scala:9: error: No ClassTag available for T1
+ def unzip3[T1, T2, T3](a: Array[(T1, T2, T3)]): (Array[T1], Array[T2], Array[T3]) = a.unzip3
+ ^
+two errors found
diff --git a/test/files/neg/t8372.scala b/test/files/neg/t8372.scala
new file mode 100644
index 0000000000..60a674f4d8
--- /dev/null
+++ b/test/files/neg/t8372.scala
@@ -0,0 +1,10 @@
+class t8372 {
+ // failed with "error: tpe T1 is an unresolved spliceable type"; that was caused by
+ // misguided type inference of type parameters in ArrayOps.unzip
+ // the type inference failed because the order of implicit arguments was wrong
+ // the evidence that T <: (T1, T2) came as last argument so it couldn't guide the
+ // type inference early enough
+ def unzip[T1, T2](a: Array[(T1, T2)]) = a.unzip
+ // the same as above
+ def unzip3[T1, T2, T3](a: Array[(T1, T2, T3)]): (Array[T1], Array[T2], Array[T3]) = a.unzip3
+}
diff --git a/test/files/pos/t8369a.check b/test/files/pos/t8369a.check
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/files/pos/t8369a.check
diff --git a/test/files/pos/t8369a.scala b/test/files/pos/t8369a.scala
new file mode 100644
index 0000000000..0596fdaf74
--- /dev/null
+++ b/test/files/pos/t8369a.scala
@@ -0,0 +1,5 @@
+object Bug {
+ trait Sys[S]
+ def test[S <: Sys[S]] = read[S]()
+ def read[S <: Sys[S]](baz: Any = 0): Some[S] = ???
+} \ No newline at end of file
diff --git a/test/files/pos/t8369b.check b/test/files/pos/t8369b.check
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/files/pos/t8369b.check
diff --git a/test/files/pos/t8369b.scala b/test/files/pos/t8369b.scala
new file mode 100644
index 0000000000..8145911db1
--- /dev/null
+++ b/test/files/pos/t8369b.scala
@@ -0,0 +1,18 @@
+object Bug {
+ trait Sys[S] {
+ type Tx
+ }
+
+ trait Baz[-Tx]
+
+ trait Foo[S <: Sys[S]] {
+ def bar: Bar[S] = Bar.read[S]()
+ }
+
+ object Bar {
+ object NoBaz extends Baz[Any]
+
+ def read[S <: Sys[S]](baz: Baz[S#Tx] = NoBaz): Bar[S] = ???
+ }
+ trait Bar[S <: Sys[S]]
+} \ No newline at end of file