diff options
-rw-r--r-- | bincompat-backward.whitelist.conf | 99 | ||||
-rw-r--r-- | bincompat-forward.whitelist.conf | 101 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/ast/Trees.scala | 3 | ||||
-rw-r--r-- | src/library/scala/PartialFunction.scala | 2 | ||||
-rw-r--r-- | src/library/scala/collection/mutable/ArrayOps.scala | 19 | ||||
-rw-r--r-- | test/files/neg/t8372.check | 7 | ||||
-rw-r--r-- | test/files/neg/t8372.scala | 10 | ||||
-rw-r--r-- | test/files/pos/t8369a.check | 0 | ||||
-rw-r--r-- | test/files/pos/t8369a.scala | 5 | ||||
-rw-r--r-- | test/files/pos/t8369b.check | 0 | ||||
-rw-r--r-- | test/files/pos/t8369b.scala | 18 |
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 |