Skip to content
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

allow more precise type when matching parametric case classes (or extractors) #8901

Open
scabug opened this issue Oct 13, 2014 · 7 comments
Open

Comments

@scabug
Copy link

scabug commented Oct 13, 2014

Currently it is possible to match a parametric case class with correct type like so:

case class Register[T](key: Key[T], value: T)
...
x match {
  case r: Register[t] =>
    val k: Key[t] = r.key
    val v: t = r.value // matching types with the key
}

What does not work is the same while extracting values (1):

case Register[t](k, v) => // says “Register[t] does not take parameters”

When not including the name for the type, T is inferred to be Any (2):

case Register(k, v) => // T is Any here, even though Register is not covariant

There are two things which should be done:

  • allow the extraction syntax shown in (1) above
  • implicitly introduce a type with a fresh name when performing the match as in (2), leading to more precise type checking than just assuming Any instead

The second part’s current negative effect can be seen in the following (assuming generic ActorRef[-T] which only accepts messages of type T):

case class Echo[T](msg: T, replyTo: ActorRef[T])
...
x match {
  case Echo(msg, replyTo) =>
    replyTo ! msg // works by accident now because T=Any for both
    replyTo ! 42 // works as well, but should not actually work
}
@scabug
Copy link
Author

scabug commented Oct 13, 2014

Imported From: https://issues.scala-lang.org/browse/SI-8901?orig=1
Reporter: @rkuhn
See #7886

@scabug
Copy link
Author

scabug commented Oct 13, 2014

@retronym said:
I believe the unsound inference of T=Any is a duplicate of bug #7886.

Supporting pattern matching type variables in constructor patterns is an interesting idea.

@scabug
Copy link
Author

scabug commented Nov 28, 2016

@paulp said:
I +/- implemented this (via a macro!) here. It's tricky because the parser generates the wrong tree if you provide type arguments in a constructor pattern - you get an AppliedTypeTree instead of TypeApply, so it must be entirely thrown out and rebuilt.

@scabug
Copy link
Author

scabug commented Nov 29, 2016

@milessabin said:
@paulp can I persuade you to translate that to a PR against the compiler? As the tests for your macro demonstrate, this gets along very nicely with literal types, and it's something I'd love to see in TLS.

@scabug
Copy link
Author

scabug commented Nov 29, 2016

@paulp said:
If I opened a PR against the compiler it would only be for the purpose of getting it into the typelevel compiler (since there's no chance of me taking it to completion) which seems like an abuse of the PR queue.

I believe the code is unusually clear and shouldn't be difficult for someone with higher optimism to adapt into a scala PR.

@scabug
Copy link
Author

scabug commented Nov 30, 2016

@milessabin said:
If you open a PR against scala/scala then I'll commit to getting it across the finishing line. I'm not likely to have time to reimplement this myself anytime soon, so this will be your quickest route to seeing it appear in the Typelevel Scala compiler.

@scabug
Copy link
Author

scabug commented Nov 30, 2016

@paulp said:
Ok, if I can find the time somewhere.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant