-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Nonunified types in GADT pattern match #15554
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
Appears to resolve the issue if I enforce the string type explicitly like val pongBehavior: [O] => (Unit, PingMessage[O]) => (Unit, O) = [O] =>
(state: Unit, msg: PingMessage[O]) =>
msg match
case PingMessage.Ping(from) => ((), s"Pong from $from": O) |
A slightly smaller minimization without a custom type: val poly: [O] => Option[O] => O = [O] =>
(opt: Option[O]) =>
opt match
case Some(s: String) => (s: String) [error] Found: [O] => (Option[O]) => String
[error] Required: [O] => (Option[O²]) => O²
[error]
[error] where: O is a type variable
[error] O² is a type variable
[error] case Some(s: String) => (s: String)
[error] ^ The error is quite confusing here. It should be either Required: [O] => (Option[O]) => O or Required: [O²] => (Option[O²]) => O² Secondly, it seems that the problem also occurs for methods: def poly[O]: Option[O] => O =
(opt: Option[O]) =>
opt match
case Some(s: String) => (s: String) [error] Found: String
[error] Required: O
[error] case Some(s: String) => (s: String)
[error] ^^^^^^^^^ Here the problem disappears when the type ascription gets removed case Some(s: String) => s |
@prolativ expanding your example, I found another issue with inference. Should I raise a different ticket for this? val poly: [O] => Option[O] => O =
case Some(s: String) => s Missing parameter type
I could not infer the type of the parameter x$1 of expanded function:
x$1 =>
x$1 match
{
case Some(s:String) =>
s
}.
Not found: s |
I think the compiler is right rejecting this code although the compilation error might not be very informative here. The point is that val poly: [O] => Option[O] => O =
[O] => { case Some(s: String) => s } might work in the future but currently it's not possible because of
Currently we have to live with val poly: [O] => Option[O] => O =
[O] => (o: Option[O]) => o match { case Some(s: String) => s } I would expect val poly: [O] => Option[O] => O =
[O] => o => o match { case Some(s: String) => s } to work too but this fails with [error] cannot infer type; expected type <?> is not fully defined
[error] [O] => o => o match { case Some(s: String) => s }
[error] ^
[error] Not found: s
[error] [O] => o => o match { case Some(s: String) => s }
[error] ^
[error] Found: [O] => (<error cannot infer type; expected type <?> is not fully defined>) =>
[error] <error Not found: s>
[error] Required: [O] => (Option[O]) => O
[error] [O] => o => o match { case Some(s: String) => s }
[error] which indeed looks like a bug to me |
There's some funkiness that needs attention, but your minimisation is different because now the scrutinee type is co-variant. And I think the behaviour is right because O is more precise than String, so you're widening by using the type ascription, akin to expecting |
Dale and I have been looking at this further. Our current hypothesis is that the root cause here is that when a polymorphic function literal is desugared, the result type of the
where the Let's return to Dale's minimization. To keep this straight in your head, it's helpful not to reuse the same type parameter name. So the minimization becomes:
line 1 is where we say what the expected type of the polymorphic function is, and that expected type includes the information that the body's result type is But when lines 2 and 3 are desugared, the desugaring includes So we'd need to take the expected type |
Again: keep an eye out for variance. If you switch to a covariant Option/Some instead of sticking to something invariant like PingMessage/Ping was, the behaviour is going to be different. |
Compiler version
3.1.3
Minimized code
Scastie: https://scastie.scala-lang.org/omCKwdwSQ2uGyiYSPRbOLQ
Output
Expectation
Compiles successfully
The text was updated successfully, but these errors were encountered: