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

Incorrect type checking in pattern match when a class inherits a case class #9795

Open
scabug opened this issue May 27, 2016 · 6 comments
Open
Labels
fixed in Scala 3 This issue does not exist in the Scala 3 compiler (https://github.com/lampepfl/dotty/) typer
Milestone

Comments

@scabug
Copy link

scabug commented May 27, 2016

Following code looks perfectly fine, but scalac 2.11.8 generates an error message.

Code:

case class A(v: Int)
class B(v: Int) extends A(v)

object Test {
  val a = new B(1)
  a match { case A(_) => 1 }
}

Error:

error: constructor cannot be instantiated to expected type;
 found   : A
 required: B
  a match { case A(_) => 1 }
                 ^
one error found

However, if we annotate a with val a:A = new B(1), everything is fine.

@scabug
Copy link
Author

scabug commented May 27, 2016

Imported From: https://issues.scala-lang.org/browse/SI-9795?orig=1
Reporter: Fengyun Liu (liufengyun)
Affected Versions: 2.11.8

@scabug
Copy link
Author

scabug commented May 29, 2016

@som-snytt said:
Spec says constructor pattern must conform. I hope someone chimes in to say why. Maybe it made more sense when a case class could extend a case class. But current error for case class extension says, "To overcome this limitation, use extractors to pattern match on non-leaf nodes." Maybe the OP error message should give similar advice.

@scabug
Copy link
Author

scabug commented Aug 11, 2016

@SethTisue said:
I guess the spec language Andrew's referring to is SLS 8.1.6 (Constructor Patterns), "The pattern matches all objects created from constructor invocations c(...)..."

I don't know why, either.

@scabug
Copy link
Author

scabug commented Aug 11, 2016

@som-snytt said:
"it must conform to the expected type of the pattern", I believe. There could be subclasses C and D, so the idea is not to match (a: B) with C. Or maybe you want the selection x.v to mean something stable.

@scabug
Copy link
Author

scabug commented Aug 17, 2016

@SethTisue said:
ah, you're right, "it must conform to the expected type of the pattern" is the key phrase. (I had glossed over that in my reading, thinking the conformance went in the other direction.)

@scabug
Copy link
Author

scabug commented Aug 17, 2016

@som-snytt said:
That's because you're a non-conformist.

For fun,

scala> (new A("hi") { }) match { case A(s) => s }
<console>:14: error: constructor cannot be instantiated to expected type;
 found   : A(in object $iw)
 required: A(in object $iw)
       (new A("hi") { }) match { case A(s) => s }
                                      ^

@scabug scabug added this to the Backlog milestone Apr 7, 2017
@SethTisue SethTisue added the fixed in Scala 3 This issue does not exist in the Scala 3 compiler (https://github.com/lampepfl/dotty/) label Aug 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
fixed in Scala 3 This issue does not exist in the Scala 3 compiler (https://github.com/lampepfl/dotty/) typer
Projects
None yet
Development

No branches or pull requests

2 participants