Dotty: Pattern matching not match union types

Created on 12 Apr 2020  路  4Comments  路  Source: lampepfl/dotty

Minimized code

when using pattern match in union type like :

val buffer: List[String | Int | Long | Char] = List("string", 1, 2l, 'p', 3l, "sss", 2)
buffer.foreach { a =>
      a match {
        case _: String | Char => println(s"$a is ")
        case _ => println(s"$a is not ")
      }
    }

the char p is not match String | Char

Output

string is 
1 is not 
2 is not 
p is not 
3 is not 
sss is 
2 is not 

But if I put a bracket around the type:

buffer.foreach { a =>
      a match {
        case _: (String | Char) => println(s"$a is ")
        case _ => println(s"$a is not ")
      }
    }

the output is right

string is 
1 is not 
2 is not 
p is 
3 is not 
sss is 
2 is not 
bug

All 4 comments

The dotty version is 0.23.0-RC1.

note that case _: String | Char means "is a string, or is the scala.Char companion object"

Starting dotty REPL...
scala> (Char: Any) match { case _: String | Char => "yup" }                                         
val res0: String = yup

Yep, it's unfortunate but you have to write case _: (String | Char) as mentioned in http://dotty.epfl.ch/docs/reference/new-types/union-types-spec.html. No one has found a satisfying way around that (previous discussion: https://contributors.scala-lang.org/t/pre-sip-allow-in-pattern-alternatives/3043)

... on the other hand, we should emit a warning in this case since it's clear that the object Char is not reachable since the scrutinee type is String | Int | Long | Char. I've opened an issue to keep track of that: https://github.com/lampepfl/dotty/issues/8711

Was this page helpful?
0 / 5 - 0 ratings