scala3 icon indicating copy to clipboard operation
scala3 copied to clipboard

val pattern match extraction does not understand actual type (with or without type ascription.)

Open megri opened this issue 1 year ago • 4 comments

Compiler version

3.4.1

Minimized code

val Array(1: Byte) = Array[Byte](1)

https://scastie.scala-lang.org/jOpc8BDCQ7ufoAGjiycSRg 😏

Output

(Warning)

pattern's type (1 : Int) does not match the right hand side expression's type Byte […]

Expectation

I think this is a bug? I expect the lefthand 1 in val Array(1) = Array[Byte](1) to be inferred as Byte, but even with the type ascription the code generates a warning.

megri avatar May 04 '24 22:05 megri

Your expectation is https://github.com/scala/scala3/issues/16821

The bug here is that 42: Byte is not a legal literal pattern.

Welcome to Scala 2.13.14 (OpenJDK 64-Bit Server VM, Java 21.0.2).
Type in expressions for evaluation. Or try :help.


scala>

scala> 42 match { case 42: Byte => }
                         ^
       error: '=>' expected but ':' found.

scala> val Array(42: Byte) = Array[Byte](42)
                   ^
       error: ')' expected but ':' found.

scala>

som-snytt avatar May 05 '24 02:05 som-snytt

Are you testing it in 2.13 to show the expected behaviour? I'm confused.

I'm also confused about the difference in handling between <n>: Byte and <n>: Short/Int/Others as seen here:

val Array(1: Byte) = Array[Byte](1)  // pattern's type (1 : Int) does not match the right hand side expression's type Byte
val Array(1) = Array[Byte](1)        // pattern's type (1 : Int) does not match the right hand side expression's type Byte
val Array(1: Int) = Array[Byte](1)   // this case is unreachable since type Byte is not a subclass of class Int (error) + pattern's type Int does not match the right hand side expression's type Byte
val Array(1: Short) = Array[Byte](1) // this case is unreachable since type Byte is not a subclass of class Short (error) + pattern's type Short does not match the right hand side expression's type Byte

edit: at first I was confused about the errors in the above but it seems these are plain type errors.

https://scastie.scala-lang.org/PH0MCuFuTZiCVAEcCEaXLw

megri avatar May 05 '24 10:05 megri

I don't believe literal pattern syntax changed intentionally since 2.13, but see @nicolasstucki comment at https://github.com/scala/scala3/issues/16821#issuecomment-1780933782 where he expects your syntax to be accepted (whatever the semantics).

Are you testing it in 2.13 to show the expected behaviour?

Yes.

som-snytt avatar May 05 '24 14:05 som-snytt

I see, thanks for the clarification.

Seems like the real issue is an unclear specification along with a confusing warning. I tested val Array(1) = Array[Int](1) and this too gives a warning albeit a different one—it seems like the 1 in match position is ascribed a singleton type. At this point I'm not sure what I expect the behaviour to be. Perhaps literal matches should be prohibited outside of a match-context 🤔

megri avatar May 06 '24 08:05 megri