scala3
scala3 copied to clipboard
Matching `BigInt` against `Int` literal pattern leads to warning
Compiler version
3.7.0
Minimized code
//> using scala 3.7.0
@main def main(): Unit =
BigInt(1) match
case 1 => println("matched")
case _ => println("didn't match")
Output
compile
[warn] -- [E030] Match case Unreachable Warning: D:\scala\run\src\main\scala\Main.scala:7:9
[warn] 7 | case 1 => println("matched")
[warn] | ^
[warn] | Unreachable case
run
matched
Expectation
No warning.
Or, the warning is correct and pattern matching is broken. A literal pattern requires conformance, and an int is not a big int.
Welcome to Scala 2.13.16 (OpenJDK 64-Bit Server VM, Java 23.0.2).
Type in expressions for evaluation. Or try :help.
scala> BigInt(42) match { case 42 => "yes" case _ => "no" }
^
error: type mismatch;
found : Int(42)
required: scala.math.BigInt
https://scala-lang.org/files/archive/spec/3.4/08-pattern-matching.html#literal-patterns
A related issue where patmat incorrectly defers to equals is https://github.com/scala/scala3/issues/16821.
In fact, Scala 3 does not require conformance of selector and pattern type, whether the pattern is a literal or not.
scala> val x = BigInt(1)
|
val x: BigInt = 1
scala> x match { case (y: Int) => true }
|
-- Error: ----------------------------------------------------------------------
1 |x match { case (y: Int) => true }
| ^
|this case is unreachable since type BigInt is not a subclass of class Integer
1 error found
That discrepancy was not noticed when Scala 3 was first defined. Now going back and requiring conformance might break code. We need to evaluate the fallout here.