Skip to content

Commit d0f9f5f

Browse files
committed
Allow type parameters to be widened, but consider them poison
1 parent 01bb05f commit d0f9f5f

File tree

5 files changed

+46
-18
lines changed

5 files changed

+46
-18
lines changed

compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ trait ConstraintHandling {
6363
* toplevel; it is turned on again when we add parts of the scrutinee to the constraint.
6464
*/
6565
protected var canWidenAbstract: Boolean = true
66+
protected var poisoned: Set[TypeParamRef] = Set.empty
6667

6768
protected var myNecessaryConstraintsOnly = false
6869
/** When collecting the constraints needed for a particular subtyping

compiler/src/dotty/tools/dotc/core/TypeComparer.scala

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -877,9 +877,13 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
877877
override def apply(x: Boolean, t: Type) =
878878
x && t.match
879879
case t: TypeParamRef =>
880-
variance == 0 || (t.binder ne caseLambda) || t.paramName.is(WildcardParamName)
880+
variance == 0
881+
|| (t.binder ne caseLambda)
882+
|| t.paramName.is(WildcardParamName)
883+
|| { poisoned += t; true }
881884
case _ =>
882885
foldOver(x, t)
886+
883887
canWidenAbstract && acc(true, tp)
884888

885889
def tryBaseType(cls2: Symbol) = {
@@ -3110,6 +3114,7 @@ class TrackingTypeComparer(initctx: Context) extends TypeComparer(initctx) {
31103114
}
31113115

31123116
def matchCases(scrut: Type, cases: List[Type])(using Context): Type = {
3117+
var poisoned: Set[TypeParamRef] = Set.empty
31133118

31143119
def paramInstances(canApprox: Boolean) = new TypeAccumulator[Array[Type]]:
31153120
def apply(insts: Array[Type], t: Type) = t match
@@ -3121,10 +3126,10 @@ class TrackingTypeComparer(initctx: Context) extends TypeComparer(initctx) {
31213126
case entry: TypeBounds =>
31223127
val lo = fullLowerBound(param)
31233128
val hi = fullUpperBound(param)
3124-
if isSubType(hi, lo) then lo.simplified else Range(lo, hi)
3129+
if !poisoned(param) && isSubType(hi, lo) then lo.simplified else Range(lo, hi)
31253130
case inst =>
31263131
assert(inst.exists, i"param = $param\nconstraint = $constraint")
3127-
inst.simplified
3132+
if !poisoned(param) then inst.simplified else Range(inst, inst)
31283133
insts
31293134
case _ =>
31303135
foldOver(insts, t)
@@ -3152,9 +3157,14 @@ class TrackingTypeComparer(initctx: Context) extends TypeComparer(initctx) {
31523157

31533158
def matches(canWidenAbstract: Boolean): Boolean =
31543159
val saved = this.canWidenAbstract
3160+
val savedPoisoned = this.poisoned
31553161
this.canWidenAbstract = canWidenAbstract
3162+
this.poisoned = Set.empty
31563163
try necessarySubType(scrut, pat)
3157-
finally this.canWidenAbstract = saved
3164+
finally
3165+
poisoned = this.poisoned
3166+
this.poisoned = savedPoisoned
3167+
this.canWidenAbstract = saved
31583168

31593169
def redux(canApprox: Boolean): MatchResult =
31603170
caseLambda match

tests/neg/6570-1.check

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@
2424
|
2525
| trying to reduce M[T]
2626
| failed since selector T
27-
| does not match case Cov[x] => N[x]
28-
| and cannot be shown to be disjoint from it either.
27+
| does not uniquely determine parameter x in
28+
| case Cov[x] => N[x]
29+
| The computed bounds for the parameter are:
30+
| x >: Box[Int]
2931
|
3032
| longer explanation available when compiling with `-explain`

tests/neg/i11982a.check

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@
77
|
88
| trying to reduce Tuple.Tail[X]
99
| failed since selector X
10-
| does not match case _ *: xs => xs
11-
| and cannot be shown to be disjoint from it either.
10+
| does not uniquely determine parameter xs in
11+
| case _ *: xs => xs
12+
| The computed bounds for the parameter are:
13+
| xs >: Any *: EmptyTuple.type <: Tuple
1214
|
1315
| longer explanation available when compiling with `-explain`
1416
-- [E057] Type Mismatch Error: tests/neg/i11982a.scala:10:38 -----------------------------------------------------------
@@ -20,8 +22,10 @@
2022
|
2123
| trying to reduce Tuple.Tail[X]
2224
| failed since selector X
23-
| does not match case _ *: xs => xs
24-
| and cannot be shown to be disjoint from it either.
25+
| does not uniquely determine parameter xs in
26+
| case _ *: xs => xs
27+
| The computed bounds for the parameter are:
28+
| xs >: Any *: EmptyTuple.type <: Tuple
2529
|
2630
| longer explanation available when compiling with `-explain`
2731
-- [E057] Type Mismatch Error: tests/neg/i11982a.scala:12:25 -----------------------------------------------------------
@@ -33,7 +37,9 @@
3337
|
3438
| trying to reduce Tuple.Tail[X]
3539
| failed since selector X
36-
| does not match case _ *: xs => xs
37-
| and cannot be shown to be disjoint from it either.
40+
| does not uniquely determine parameter xs in
41+
| case _ *: xs => xs
42+
| The computed bounds for the parameter are:
43+
| xs >: Any *: EmptyTuple.type <: Tuple
3844
|
3945
| longer explanation available when compiling with `-explain`

tests/neg/i13780.check

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,11 @@
1111
|
1212
| trying to reduce Head[X]
1313
| failed since selector X
14-
| does not match case (a, b) => a
15-
| and cannot be shown to be disjoint from it either.
14+
| does not uniquely determine parameters a, b in
15+
| case (a, b) => a
16+
| The computed bounds for the parameters are:
17+
| a >: Any
18+
| b >: Any
1619
|
1720
| longer explanation available when compiling with `-explain`
1821
-- [E007] Type Mismatch Error: tests/neg/i13780.scala:18:31 ------------------------------------------------------------
@@ -28,8 +31,11 @@
2831
|
2932
| trying to reduce Head[X]
3033
| failed since selector X
31-
| does not match case (a, b) => a
32-
| and cannot be shown to be disjoint from it either.
34+
| does not uniquely determine parameters a, b in
35+
| case (a, b) => a
36+
| The computed bounds for the parameters are:
37+
| a >: Int
38+
| b >: Int
3339
|
3440
| longer explanation available when compiling with `-explain`
3541
-- [E007] Type Mismatch Error: tests/neg/i13780.scala:23:37 ------------------------------------------------------------
@@ -45,7 +51,10 @@
4551
|
4652
| trying to reduce Head[X]
4753
| failed since selector X
48-
| does not match case (a, b) => a
49-
| and cannot be shown to be disjoint from it either.
54+
| does not uniquely determine parameters a, b in
55+
| case (a, b) => a
56+
| The computed bounds for the parameters are:
57+
| a >: String
58+
| b >: String
5059
|
5160
| longer explanation available when compiling with `-explain`

0 commit comments

Comments
 (0)