Open bishabosha opened 2 years ago
is this possible?
Doesn't 0
match S[-1]
?
Doesn't 0 match S[-1]?
type Foo[I <: Int] <: Int = I match { case compiletime.ops.int.S[n] => n }
scala> val m: Foo[1] = 0
val m: 0 = 0
scala> val m: Foo[0] = -1
-- [E007] Type Mismatch Error: -------------------------------------------------
1 |val m: Foo[0] = -1
| ^^
| Found: (-1 : Int)
| Required: Foo[(0 : Int)]
|
| Note: a match type could not be fully reduced:
|
| trying to reduce Foo[(0 : Int)]
| failed since selector (0 : Int)
| does not match case compiletime.ops.int.S[n] => n
| and cannot be shown to be disjoint from it either.
scala> val m: Foo[-1] = -2
-- [E007] Type Mismatch Error: -------------------------------------------------
1 |val m: Foo[-1] = -2
| ^^
| Found: (-2 : Int)
| Required: Foo[(-1 : Int)]
|
| Note: a match type could not be fully reduced:
|
| trying to reduce Foo[(-1 : Int)]
| failed since selector (-1 : Int)
| does not match case compiletime.ops.int.S[n] => n
| and cannot be shown to be disjoint from it either.
Glancing, it looks like this is already special-cased in TypeComparer: https://github.com/lampepfl/dotty/blob/482c67e894805c83e256c22f2106929b28366e77/compiler/src/dotty/tools/dotc/core/TypeComparer.scala#L1261
Personally I would rather not continue to special-case here and there, but rather implement a general way to declare sealed types. But then I would say that...
If this is still desired, it should be brought up in SIP-56 Proper Specification for Match Types. After, it will be too late.
@sjrd given that S
is getting a special case in the logic of match types, then it wouldn't be too far of a stretch to add it to disjointness maybe?
It would be useful if
0
andS[n]
could be treated as provably disjoint - currently you need to make aNat
enum to get sensible behaviour from match types, howeverNat
is inefficient to materialiseOriginally posted by @bishabosha in https://github.com/lampepfl/dotty/issues/14549#issuecomment-1050881334:
I think really the issue is that
0
andS[n]
are not treated like independent class types, for example, if we substituteInt
for someNat
enum then the example works unchanged: