-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Use union of cases as default bound of match types #8085
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
Conversation
@@ -1498,7 +1498,10 @@ class Typer extends Namer | |||
val sel1 = typed(tree.selector) | |||
val pt1 = if (bound1.isEmpty) pt else bound1.tpe | |||
val cases1 = tree.cases.mapconserve(typedTypeCase(_, sel1.tpe, pt1)) | |||
assignType(cpy.MatchTypeTree(tree)(bound1, sel1, cases1), bound1, sel1, cases1) | |||
val bound2 = | |||
if (tree.bound.isEmpty) TypeTree(cases1.map(_.body.tpe).reduce(_ | _)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't this cause problems when body
contains references to type variables extracted from a type pattern?
As in: ... match { case List[t] => t }
ee10fce
to
7ae11ad
Compare
7ae11ad
to
a6c62c4
Compare
This change doesn't work well with nested matches. For instance, lets have a look at type Elem[X <: Tuple, N <: Int] <: Any = X match {
case x *: xs =>
N match {
case 0 => x
case S[n1] => Elem[xs, n1]
}
} With this change, the inner type The main issue here is that we don't have syntax to specify bounds outside of type definition, meaning the above would have to be rewritten as: type Elem[X <: Tuple, N <: Int] <: Any = X match {
case x *: xs => Elem0[N, x, xs]
}
type Elem0[N <: Int, X <: Any, XS <: Tuple] <: Any match {
case 0 => X
case S[n1] => Elem[XS, n1]
} Assuming we had better syntax for that, there is some more work needed to make this change viable: the compiler needs the detect cycles and report an error similar to what we have for recursive functions ("recursive match type need explicit bounds"). I think that might bit tricky to implement, given that the cyclic references are only triggered at use site (during subtyping), we would have some additional mechanism when compiling a match type to detect these and error out accordingly. |
I see, thanks for looking into it @OlivierBlanvillain! It seems to me that the appropriate thing to do here would be type avoidance of the types being defined while computing the match type bounds, using the bounds actually specified by the user. So instead of I don't know whether that could be done easily, though. |
Fix lampepfl/dotty-feature-requests#90
This PR implements what @LPTK suggested at the end of the issue, which is to use the union of cases as the bound of match types when no bounds are provided.
Unfortunatly the snippet from the linked issue still doesn't compile, but I think the remaining issue might be unrelated to match type (see #8084).