-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Treat opaque types as abstract during patmat exhaustivity tests #5467
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
I'm not sure, but this seems to be the most relevant to issue I got into: I would expect it to match on newtype, or at least fail at compile time opaque type Email = String
object Email {
def apply(email: String): Email = email
}
opaque type Phone = String
object Phone {
def apply(nr: String): Phone = nr
}
type EmailOrPhone = Email | Phone
object Main {
def sayIt(u: EmailOrPhone): String = u match {
case Email => "It's an email"
case Phone => "It's a phone number"
}
def main(args: Array[String]): Unit = {
println(sayIt(Email("somebody@somewhere")))
}
} This compiles but fails with:
What behavior is designed for this case? |
You're matching on the value of the object |
@smarter ohh, didn't think of that :). Then here is the next one: opaque type Email = String
object Email {
def apply(email: String): Email = email
}
opaque type Phone = String
object Phone {
def apply(nr: String): Phone = nr
}
type EmailOrPhone = Email | Phone
object Main {
def sayIt(u: EmailOrPhone): String = u match {
case _: Phone => "It's a phone number"
case _: Email => "It's an email"
}
def main(args: Array[String]): Unit = {
println(sayIt(Email("somebody@somewhere")))
println(sayIt(Phone("123123123")))
}
} It gives a warning, but I probably have wrong expectations from opaque types:
|
Yes, this is normal, |
For the record, we very likely should always emit a warning whenever we see a typecase pattern for an opaque type. |
Compiling the following code:
emits a warning like this:
and it should emit a warning like this:
See discussion starting around #5300 (comment).
To sum up the discussion we had about this, the issue happens because
opaque
aliases are revealed duringElimOpaque
phase, which happens before exhaustivity checks. To fix this, their order should be reversed. We should be careful with movingElimOpaque
further (in particular we should not move it right before erasure), since warnings & optimisations currently afterElimOpaque
may actually want to see through the opaque alias. It may be easier to instead move exhaustivity checks beforeElimOpaque
.The text was updated successfully, but these errors were encountered: