-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
AST owner loss during a type match #17192
Comments
The problem is class C[A]:
type T = A match
case true => this.type
implicitly[this.type =:= T]
val a = new C[true] This leads us to have -- [E172] Type Error: ------------------------------------------------------------------
4 | implicitly[this.type =:= T]
| ^
| Cannot prove that (C.this : C[A]) =:= C.this.T. The most interesting thing is: class C[A]:
type X = A match
case _ => this.type
implicitly[X =:= this.type]
val a = new C[true] Will work. We can use anything instead of So moving match types outside simply don't do anything. |
Hi Decel, I am not sure to understand what you are suggesting. The two snippets you suggests, do behave as expected. class C[A]:
type T = A match
case true => this.type
implicitly[this.type =:= T] // Fails BB: class C[A]:
type T = A match
case _ => this.type
implicitly[this.type =:= T] // Works
What is the relation with the compiler crash (assertion failure on missing AST Symbol owner) described in the ticket ? |
Oops, closed by mistake, reopening. |
The problem is, even if we add a case for non-true cases in AA: class C[A]:
type X = A match
case true => true
case _ => true
type Y = A match
case _ => true
implicitly[X =:= Y] These match types are equivalent for any type of We could fix your snippet in the same fashion: class Ifce[BT <: Boolean] extends Selectable:
type RT = BT match {
case _ => this.type { val v1: Int }
}
def cast : RT = this.asInstanceOf[RT]
def selectDynamic(key:String) : Any = ???
val full = (new Ifce[true]).cast
println(s"full.v1 = ${full.v1}") |
Mhhh, not convinced. Code below fails : class Ifce[BT <: Boolean]:
type RT = BT match {
case true => this.type { val v1: Int }
}
def cast : RT = this.asInstanceOf[RT]
val full /*: Ifce[true] {val v1:Int} */ = (new Ifce[true]).cast
println(s"full.v1 = ${full.v1}") But doing the type ascription (removing the comment) makes it compile. It is very possible that other resolutions of the match type (for instance those which always succeed, and may be resolved in an earlier phase, when the type parameter is still unknown) do not get corrupted. Anyway, a failing type-conformance test should not result in a compiler crash. |
Interestingly, if we change the definition of type RT =
this.type { val v1: Int } or type RT = BT match {
case _ => this.type { val v1: Int }
} we get the following compile error:
So my feeling is that it's not really an owner chain issue (in fact that would be very surprising because Types are not AST based and don't have owners; only Trees and Symbols do). Instead, it is the Indeed, after typer on the minimization of the previous post, we still see a bare selection final module class Test() extends Object() { this: Test.type =>
def main(args: Array[String]): Unit =
{
val full: Ifce[(true : Boolean)]#RT = new Ifce[true.type]().cast
val v1: Int = full.v1
}
} which is a val v1: Int = reflect.Selectable.reflectiveSelectable(full).selectDynamic("v1").$asInstanceOf[Int] assuming we added the correct import of import reflect.Selectable.reflectiveSelectable In conclusion, while a match type is required to trigger the crash, I believe the problem is situated more in the treatment of |
Compiler version
3.2.2, 3.3.0-RC3
Minimized code
Output
scala java.lang.AssertionError: assertion failed: no owner from / in Playground.full.v1
Observations
The crash is related to the type match. Following code does not crash.
When the type match is defined outside the class, no crash either.
extending
trait Selectable
is not involved. Following code does crash.The text was updated successfully, but these errors were encountered: