scala / scala3

The Scala 3 compiler, also known as Dotty.
https://dotty.epfl.ch
Apache License 2.0
5.72k stars 1.04k forks source link

The match type contains an illegal case; what makes it illegal? #20266

Open Adam-Vandervorst opened 2 months ago

Adam-Vandervorst commented 2 months ago

Compiler version

3.4.1

Minimized example

trait Poly
trait -->[X <: Poly, Y <: Poly] extends Poly
trait +[X <: Poly, Y <: Poly] extends Poly
trait *[X <: Poly, Y <: Poly] extends Poly

type Hinze[X <: Poly] = X match {
  case (k1 + k2) --> v => (k1 --> v) * (k2 --> v)
  case (k1 * k2) --> v => k1 --> (k2 --> v)
}

Output Error/Warning message

                    The match type contains an illegal case:
                        case (k1 + k2) --> v => (k1 --> v) * (k2 --> v)
                    (this error can be ignored for now with `-source:3.3`)

Why this Error/Warning was not helpful

The message was unhelpful because it only stated there was a problem, not what that problem was. It takes significant time to figure that out (I've tried with and without infix notation and with and without parenthesis).

Suggested improvement

It could be made more helpful by additionally stating (just for illustration), "Unbound variables in the LHS of a match type case need a type upper bound".

Note

I still don't know why I -source:3.3 to make this compile.

bishabosha commented 2 months ago

great issue, thanks for reporting! I agree it would be good to see a suggestion of what is the problem precisely

if you didn't already find out why, this is one way to fix the error:

type Hinze[X <: Poly] = X match {
  case foo --> v => foo match {
    case (k1 + k2) => (k1 --> v) * (k2 --> v)
    case (k1 * k2) => k1 --> (k2 --> v)
  }
}

if you want some intuition, match types resolve with similar semantics to what an equivalent runtime match expression would. And at runtime you can only type-test on the erased class type.