-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Missed match on Array(1L) in Scala 3.1.1 #14693
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Dale (@dwijnand) has been working in this area recently. is the problem reproducible in 3.1.2-RC2 and/or in the latest nightly (3.2.0-RC1-bin-20220308-29073f1-NIGHTLY-git-29073f1)? |
|
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
I think the problem is with the definition of Array.unapplySeq, if I tweak it like this: diff --git src/library/scala/Array.scala src/library/scala/Array.scala
index 14cdabd385..a64ae3cb8c 100644
--- src/library/scala/Array.scala
+++ src/library/scala/Array.scala
@@ -574,9 +574,9 @@ object Array {
* @param x the selector value
* @return sequence wrapped in a [[scala.Some]], if `x` is an Array, otherwise `None`
*/
- def unapplySeq[T](x: Array[T]): UnapplySeqWrapper[T] = new UnapplySeqWrapper(x)
+ def unapplySeq[T](x: Array[? <: T]): UnapplySeqWrapper[T] = new UnapplySeqWrapper(x)
- final class UnapplySeqWrapper[T](private val a: Array[T]) extends AnyVal {
+ final class UnapplySeqWrapper[T](private val a: Array[? <: T]) extends AnyVal {
def isEmpty: false = false
def get: UnapplySeqWrapper[T] = this
def lengthCompare(len: Int): Int = a.lengthCompare(len) Then the pattern match succeeds. Otherwise, depending on how unapplySeq is instantiated, we'll end up matching either all arrays or only arrays of objects, because I believe this would be a binary-compatible change, so there's a chance we could just apply this diff in the Scala 2 standard library. |
Fixes scala/scala3#14693, see discussion in the issue.
Fixes scala/scala3#14693, see discussion in the issue.
I've just now realized that the way we type Array.unapplySeq in patterns is specific to the fact that it's define in a Scala 2 class, if I define my own extractor, then the match succeeds: object UnapSeq {
def unapplySeq[T](x: Array[T]): Array.UnapplySeqWrapper[T] = new Array.UnapplySeqWrapper[T](x)
}
object Test {
val a: Array[Long] = Array(1L)
def test(x: Any) = x match {
case UnapSeq(i: Long) => println("Success!")
case _ => println("Failure!") }
def main(args: Array[String]): Unit = test(a)
} The culprit is the use of fromScala2x in https://github.com/lampepfl/dotty/blob/fb7f900667ea57e78a098e4831be36e0a7da6cba/compiler/src/dotty/tools/dotc/typer/Applications.scala#L1346 @odersky do you think we could get rid of fromScala2x in typedUnapply or at least tweak it to fix this? |
It seems our GADT handling is now able to do without. Fixes scala#14693
Observation
Consider the following code:
When run under Scala 2.13.8 this produces
Success
whereas under Scala 3.1.1 it producesFailure
. For the latter it does not matter if the compiler option-source:3.0-migration
is used.Expectation
Same behaviour under both versions or (at least) a warning that the match will fail. Current situation significantly changes runtime behaviour after migrating projects from Scala 2 to Scala 3.
The text was updated successfully, but these errors were encountered: