-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Inline matches don't refine on the RHS #5564
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've taken a look at this and it seems that we cannot allow this code to compile, since This very similar example compiles with #5657 (and may even compile on master): object `inline-match-gadt` {
class Exactly[T]
erased def exactType[T]: Exactly[T] = ???
inline def foo[T](t: T): T =
inline exactType[T] match {
case _: Exactly[Int] => 23
case _ => t
}
} @milessabin do you think we should add something like |
@AleksanderBG gotcha. I think we need to think a bit more about things like In any case the following also works on master, object Test {
import scala.typelevel._
type Inv[t] = t
inline def foo[T](t: T): T =
inline erasedValue[Inv[T]] match {
case _: Int => 23
case _ => t
}
} so we could tweak |
@milessabin Regarding object Test {
import scala.typelevel._
inline def foo[T](t: T): T = inline erasedValue[T] match {
case _: Int => 23
case _ => t
}
val notFive: 5 = foo[5](5) // === 23 ! To allow this code to compile, we would need to reduce typecase patterns only if they are equivalent to scrutinee type, but this seems to me even more surprising - consider: object Test {
inline def test = {
inline val five = 5 // five is of type 5
inline five match {
case _: Int => true
case _ => false
}
}
val doesFiveMatchInt = test // false !
} Also note that your last example also allows returning 23 as a value of type To sum up: I think it's clear that the interaction between object Test {
final abstract class Type[-A, +B]
erased def typeof[T]: Type[T, T] = ???
type Exactly[t]= Type[t, t]
type Subtype[t] = Type[_, t]
type Supertype[t] = Type[t, _]
inline def isExactlyInt[t] = inline typeof[t] match {
case _: Exactly[Int] => true
case _ => false
}
isExactlyInt[Int] // true
isExactlyInt[5] // false
inline def isSubOfInt[t] = inline typeof[t] match {
case _: Subtype[Int] => true
case _ => false
}
isSubOfInt[Int] && isSubOfInt[5] // true
} Alternatively, we could add special syntax for inline type matches. The downside I'm seeing immediately is that it'd be no longer possible to match both on a value and a type at the same time. I'll think about it a little bit more and open a PR/issue later. |
Ahh ... I'd missed that the use of the Anyhow, all understood. I like the look of @odersky I think we should replace |
@milessabin the reason why I don't want to merge this outright is:
See #5683, in particular the annoying changes in |
@biboudis @nicolasstucki I think this issue perfectly captures what we talked about on Monday. In particular see my comment #5564 (comment) which goes in detail on why we cannot allow |
@nicolasstucki can you go through this issue and decide to either close it or keep it? |
Uh oh!
There was an error while loading. Please reload this page.
Equalities between types established by the cases of inline matches aren't known on the RHS,
Adding a cast allows this to compile,
The text was updated successfully, but these errors were encountered: