bug icon indicating copy to clipboard operation
bug copied to clipboard

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

Open scabug opened this issue 11 years ago • 8 comments

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 avatar Oct 13 '14 08:10 scabug

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

scabug avatar Oct 13 '14 08:10 scabug

@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 avatar Oct 13 '14 08:10 scabug

@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 avatar Nov 28 '16 18:11 scabug

@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 avatar Nov 29 '16 14:11 scabug

@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 avatar Nov 29 '16 23:11 scabug

@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 avatar Nov 30 '16 13:11 scabug

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

scabug avatar Nov 30 '16 17:11 scabug

someone want to check if this is still reproducible in current Scala 2 and/or 3?

SethTisue avatar Mar 06 '25 22:03 SethTisue