Skip to content

pattern matching generic case classes might be too strict #2675

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

Closed
rkuhn opened this issue Jun 4, 2017 · 3 comments
Closed

pattern matching generic case classes might be too strict #2675

rkuhn opened this issue Jun 4, 2017 · 3 comments

Comments

@rkuhn
Copy link

rkuhn commented Jun 4, 2017

Consider the following example:

class Ref[-T]

sealed trait Op
case class Send[T](ref: Ref[T], msg: T) extends Op

object Main {
  val ref: Ref[String] = ???
  val op: Op = Send(ref, "hello")
  op match {
    case Send(ref, msg) => 
  }
}

Compiling this with dotty 0.1.2-RC1 yields:

[warn] -- Warning: /Users/rkuhn/comp/test/dotty/dotty-project-template/src/main/scala/Main.scala:10:13 
[warn] 10 |    case Send(target, msg) => 
[warn]    |         ^^^^^^^^^^^^^^^^^
[warn]    |         There is no best instantiation of pattern type Send[Any^]
[warn]    |         that makes it a subtype of selector type Op.
[warn]    |         Non-variant type variable T cannot be uniquely instantiated.
[warn]    |         (This would be an error under strict mode)
[warn] one warning found

The important knowledge encapsulated by the Send type is that it has been constructed with ref and msg matching each other. When pattern matching on such a type, I don’t care what the type parameter was, I only care that it was the same for the ref and the msg. Why can’t dotty just make up a type parameter that is not bound and use that in the case statement?

@curoli
Copy link

curoli commented Jun 5, 2017

Why not just case send: Send[_]?

@rkuhn
Copy link
Author

rkuhn commented Jun 5, 2017

Indeed, that works, as does case s: Send[t]. This begs the question as to why the warning/error is raised: clearly there is a way to express “some instantiation of T” within dotty’s type system.

@Blaisorblade
Copy link
Contributor

Why can’t dotty just make up a type parameter that is not bound and use that in the case statement?

According to @smarter, Dotty can, but this needs to be implemented. There are also examples which are more complicated—and GADTs are hard.

odersky added a commit to dotty-staging/dotty that referenced this issue Jan 25, 2018
In non-variant contexts, we used to always maximize them, but this is unsound.
See neg/patternUnsoundness.scala. We now create fresh abstract types in
these situations.
@smarter smarter closed this as completed in 9ea9ef4 Feb 1, 2018
smarter added a commit that referenced this issue Feb 1, 2018
Fix #2675: Properly handle undetermined type variables in unapply
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

4 participants