Commit 07f9303
committed
Fix #5077: avoid pattern-bound type for selectors
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.1 parent 2457371 commit 07f9303
File tree
3 files changed
+49
-5
lines changed- compiler/src/dotty/tools/dotc/transform
- tests/run
3 files changed
+49
-5
lines changedLines changed: 13 additions & 5 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
94 | 94 | | |
95 | 95 | | |
96 | 96 | | |
97 | | - | |
| 97 | + | |
98 | 98 | | |
99 | | - | |
| 99 | + | |
100 | 100 | | |
101 | 101 | | |
102 | 102 | | |
103 | | - | |
104 | | - | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
105 | 106 | | |
106 | 107 | | |
107 | 108 | | |
| |||
223 | 224 | | |
224 | 225 | | |
225 | 226 | | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
226 | 234 | | |
227 | 235 | | |
228 | 236 | | |
| |||
243 | 251 | | |
244 | 252 | | |
245 | 253 | | |
246 | | - | |
| 254 | + | |
247 | 255 | | |
248 | 256 | | |
249 | 257 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
0 commit comments