Commit 78e7163
authored
Fix spurious subtype check pruning when both sides have unions (#18213)
Fixes #17465.
In TypeComparer, `fourthTry` calls `isNewSubType` and `isCovered` to
detect the subtype queries that have been covered by previous attempts
and prune them. However, the pruning is spurious when both sides contain
union types, as exemplified by the following subtype trace before the
PR:
```
==> isSubType (test1 : (Int | String){def foo(x: Int): Int}) <:< Int | String?
==> isSubType (Int | String){def foo(x: Int): Int} <:< Int | String?
==> isSubType (Int | String){def foo(x: Int): Int} <:< Int?
<== isSubType (Int | String){def foo(x: Int): Int} <:< Int = false
==> isSubType (Int | String){def foo(x: Int): Int} <:< String?
==> isSubType (Int | String){def foo(x: Int): Int} <:< String?
<== isSubType (Int | String){def foo(x: Int): Int} <:< String = false
<== isSubType (Int | String){def foo(x: Int): Int} <:< String = false
// (1): follow-up subtype checks are pruned here by isNewSubType
<== isSubType (Int | String){def foo(x: Int): Int} <:< Int | String = false
<== isSubType (test1 : (Int | String){def foo(x: Int): Int}) <:< Int | String = false
```
At `(1)`, the pruning condition is met, and follow-up recursions are
skipped. However, in this case, only after `(1)` are the refinement on
LHS dropped and the subtype between two identical OrTypes are accepted.
The pruning is spurious.
This PR tempers the pruning conditions specified in `isCovered` and
`isNewSubType` to fix these false negatives.File tree
2 files changed
+77
-14
lines changed- compiler/src/dotty/tools/dotc/core
- tests/pos
2 files changed
+77
-14
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1487 | 1487 | | |
1488 | 1488 | | |
1489 | 1489 | | |
| 1490 | + | |
| 1491 | + | |
| 1492 | + | |
| 1493 | + | |
| 1494 | + | |
| 1495 | + | |
| 1496 | + | |
1490 | 1497 | | |
1491 | 1498 | | |
1492 | | - | |
| 1499 | + | |
| 1500 | + | |
| 1501 | + | |
| 1502 | + | |
| 1503 | + | |
| 1504 | + | |
| 1505 | + | |
| 1506 | + | |
| 1507 | + | |
| 1508 | + | |
| 1509 | + | |
| 1510 | + | |
| 1511 | + | |
| 1512 | + | |
| 1513 | + | |
1493 | 1514 | | |
1494 | 1515 | | |
1495 | 1516 | | |
| |||
2099 | 2120 | | |
2100 | 2121 | | |
2101 | 2122 | | |
2102 | | - | |
2103 | | - | |
2104 | | - | |
2105 | | - | |
2106 | | - | |
2107 | | - | |
2108 | | - | |
2109 | | - | |
2110 | | - | |
2111 | | - | |
2112 | | - | |
2113 | | - | |
2114 | | - | |
2115 | 2123 | | |
2116 | 2124 | | |
2117 | 2125 | | |
| |||
3000 | 3008 | | |
3001 | 3009 | | |
3002 | 3010 | | |
| 3011 | + | |
| 3012 | + | |
| 3013 | + | |
| 3014 | + | |
| 3015 | + | |
| 3016 | + | |
| 3017 | + | |
| 3018 | + | |
| 3019 | + | |
| 3020 | + | |
3003 | 3021 | | |
3004 | 3022 | | |
3005 | 3023 | | |
| |||
| 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 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
0 commit comments