-
Notifications
You must be signed in to change notification settings - Fork 1.1k
inconsistency between path-dependent and projection type matching #16728
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
What does Scala-2 do for this? |
Scala 2 compliant version: class A {
class X {
def outer : A.this.type = A.this
}
}
class B extends A
class C extends A
object Main {
def main(args: Array[String]) : Unit = {
val b0 = new B
val b1 = b0
val b2 = new B
val c0 = new C
val c1 = c0
val c2 = new C
val b0x : A#X = new b0.X
val pathTypeMatch = b0x match {
case _ : c2.X => "c2.X"
case _ : c1.X => "c1.x"
case _ : c0.X => "c0.X"
case _ : b2.X => "b2.X"
case _ : b1.X => "b1.X"
case _ : b0.X => "b0.X"
case _ => "ELSE"
}
println(pathTypeMatch)
val projectionTypeMatch = b0x match {
case _ : C#X => "C#X"
case _ : B#X => "B#X"
case _ : A#X => "A#X"
case _ => "ELSE"
}
println(projectionTypeMatch)
val failingTypeMatch = b0x match {
case cx : C#X =>
val c : C = cx.outer
c
}
println(failingTypeMatch)
}
} Running this snippet outputs:
|
@prolativ Thanks for the quick diagnosis! I also think that the behavior as observed does not match the spec. But if we change the code generation to match the spec, we change the runtime behavior of (possibly a lot of) existing code. Is it worth it? Or should we change the spec to something like the following?
If we do that, we should probably also issue an unchecked warning. |
Type projections have been fundamentally revised in scala3 to make them sound. Is it not the opportunity to align the behavior with the expectations ? Besides, I believe that in many cases, the change of runtime will actually fix a former mishap behavior :-). |
@odersky We can always run a full community build with a new code generation to see if there were any projects depending on the old behavior. I really doubt that as it was rather useless and the behavior from the spec is much more intuitive. |
There must be a way to qualify the situation where the discrepancy between the spec and the (old) behavior appears. Something like "a pattern matching on a projection type
The condition looks impossible to verify if |
A type pattern of the form A#B should be checked if the prefix A is not already the owner of B or a superclass. Fixes scala#16728
Great ! Thank you. |
Hello ! Could a PR be opened to integrate fix above ? |
A type pattern of the form A#B should be checked if the prefix A is not already the owner of B or a superclass. Fixes scala#16728
Uh oh!
There was an error while loading. Please reload this page.
Compiler version
3.2.2
Minimized code
Output
Expectation
Path-dependent type matching behaves as expected.
b0x
is indeed ab1.X
.Projection type matching is inconsistent.
b0x
is not aC#X
, but aB#X
.Once in the branch, the legitimate type-ascription of
(cx:C#X).outer
to typeC
throws the exception.Apparently,
B#X
andC#X
have a type erasure inA#X
. In the byte code, the condition of all 3 branches are strictly identical (isinstance A$X). Thus, branchesB#X
andA#X
are actually unreachable.The paragraph below suggests the intention to take the prefix into account for the match.
https://scala-lang.org/files/archive/spec/2.13/08-pattern-matching.html#type-patterns
Besides, https://scala-lang.org/files/archive/spec/2.13/03-types.html#type-erasure states:
Here,
C
is concrete, so the erasure ofC#X
is expected to beC#X
, notA#X
.The text was updated successfully, but these errors were encountered: