You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Given the following definition:
trait Is[A]
case object IsInt extends Is[Int]
case object IsString extends Is[String]
case class C[A](is: Is[A], value: A)
and the pattern match:
(x: C[_]) match
case C(IsInt, i) => ...
The typer (enhanced with GADT) will infer `C[A$1]` as the type of the
pattern, where `A$1 =:= Int`.
The patternMatcher generates the following code:
case val x15: C[A$1] =
C.unapply[A$1 @ A$1](x9.$asInstanceOf$[C[A$1]])
case val x16: Is[A$1] = x15._1
case val x17: A$1 = x15._2 // erase to `Int`
if IsInt.==(x16) then
{
case val i: A$1 = x17
...
}
Note that `x17` will have the erased type `Int`. This is incorrect: it
may only assume the type `Int` if the test is true inside the block.
If the test is false, we will get an type cast exception at runtime.
To fix the problem, we replace pattern-bound types by `Any` for
selector results:
case val x15: C[A$1] =
C.unapply[A$1 @ A$1](x9.$asInstanceOf$[C[A$1]])
case val x16: Is[A$1] = x15._1
case val x17: Any = x15._2
if IsInt.==(x16) then
{
case val i: A$1 = x17.$asInstanceOf$[A$1]
...
}
The patternMatcher will then use a type cast to pass the selector
value for nested unapplys or assign it to bound variables.
0 commit comments