trait Foo; trait Bar
type Res[X] = X match {
case Foo => String
case Bar => Int
}
0: Res[Bar]
1 |0: Res[Bar]
|^
|Found: (0 : Int)
|Required: Res[Bar]
It works as expected if you change the traits to classes, or if you reverse the order of the cases.
That's working as intended. Reducing Res[Bar] to Int would be unsound, and once we merge #8024 it's going to be trivial to make a counter example. Given the Res type you defined above, the following typechecks (after #8024):
def res[X](x: X): Res[X] = x match {
case _: Foo => String
case _: Bar => Int
}
However, if Res[Bar] where to reduce to Int, we would be able to use multiple inheritence to get a class cast exception:
class Boom extends Foo with Bar
val i: Int = res[Boom](new Boom())
println(i + 1) //java.lang.ClassCastException: class String cannot be cast to Integer
If Foo and Bar are classes, the compiler knows that Foo and Bar are disjoint types, in which case it's fine to do the reduction. Likewise, if you swap the order of cases, reducing to Int is also OK given that Bar (the match type's scrutinee) is a subtype of Bar (the match type's first pattern).
@OlivierBlanvillain Hmm, makes sense, thanks. This means I can't ever expect matching on function types to be useful, right, since FunctionX is a trait? My original use case looked like this:
scala> type Res[F] = F match {
| case ((a, b) => t) => String
| case ( a => t) => Int
| }
scala> 0: Res[Int => Int]
1 |0: Res[Int => Int]
|^
|Found: (0 : Int)
|Required: Res[Int => Int]
Yes, matching on fonction types isn't going to lead to anywhere. In your example I don't think functions being traits is the problem, instead is has to do with variance. Any => Int is a subtype of both Int => Int and ((a, b) => t), so it would be wrong to reduce past the first case in your last example.
I know it's currently really hard to understand why certain match types don't reduce... I plan to invest time into better error messages for match types, in the worse case something 脿 la -Xlog-implicits should be relatively easy to implement.
@OlivierBlanvillain Just to clarify for the record, I don't need to distinguish Function1[Tuple2[a, b], t] and Function1[a, t], only Function1 and Function2, so I don't think variance is the issue.