Skip to content

Commit e907df5

Browse files
committed
Fix GADT test failures
1 parent e47afef commit e907df5

File tree

1 file changed

+15
-14
lines changed

1 file changed

+15
-14
lines changed

compiler/src/dotty/tools/dotc/transform/IsInstanceOfChecker.scala

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,14 @@ object Checkable {
4545
*
4646
* Replace `T @unchecked` and pattern binder types (e.g., `_$1`) in P with WildcardType, then check:
4747
*
48-
* 1. if `P` is a singleton type, TRUE
49-
* 2. if `P` is WildcardType, TRUE
48+
* 1. if `X <:< P`, TRUE
49+
* 2. if `P` is a singleton type, TRUE
5050
* 3. if `P` refers to an abstract type member or type parameter, `X <:< P`
5151
* 4. if `P = Array[T]`, checkable(E, T) where `E` is the element type of `X`, defaults to `Any`.
5252
* 5. if `P` is `pre.F[Ts]` and `pre.F` refers to a class which is not `Array`:
5353
* (a) replace `Ts` with fresh type variables `Xs`
54-
* (b) `pre.F[Xs] <:< X` with `Xs` instantiated as `Es`
55-
* (c) `pre.F[Es] <:< P`
54+
* (b) constrain `Xs` with `pre.F[Xs] <:< X` (may fail)
55+
* (c) instantiate Xs and check `pre.F[Xs] <:< P`
5656
* 6. if `P = T1 | T2` or `P = T1 & T2`, checkable(X, T1) && checkable(X, T2).
5757
* 7. if `P` is a refinement type, FALSE
5858
* 8. otherwise, TRUE
@@ -76,33 +76,34 @@ object Checkable {
7676
val tvars = constrained(typeLambda, untpd.EmptyTree, alwaysAddTypeVars = true)._2.map(_.tpe)
7777
val P1 = tycon.appliedTo(tvars)
7878

79+
debug.println("P : " + P.show)
7980
debug.println("P1 : " + P1.show)
8081
debug.println("X : " + X.show)
8182

82-
(P1 <:< X) && {
83-
val res = isFullyDefined(P1, ForceDegree.noBottom) && P1 <:< P
84-
debug.println("P1 <:< P = " + res)
85-
res
86-
}
83+
P1 <:< X // may fail, ignore
84+
85+
val res = isFullyDefined(P1, ForceDegree.noBottom) && P1 <:< P
86+
debug.println("P1 : " + P1)
87+
debug.println("P1 <:< P = " + res)
88+
res
8789
}
8890

89-
def recur(X: Type, P: Type): Boolean = P match {
91+
def recur(X: Type, P: Type): Boolean = (X <:< P) || (P match {
9092
case _: SingletonType => true
91-
case WildcardType => true
9293
case _: TypeProxy
93-
if isAbstract(P) => X <:< P
94+
if isAbstract(P) => false
9495
case defn.ArrayOf(tpT) =>
9596
X match {
9697
case defn.ArrayOf(tpE) => recur(tpE, tpT)
9798
case _ => recur(defn.AnyType, tpT)
9899
}
99-
case tpe: AppliedType => isClassDetermined(X, tpe)
100+
case tpe: AppliedType => isClassDetermined(X, tpe)(ctx.fresh.setNewTyperState())
100101
case AndType(tp1, tp2) => recur(X, tp1) && recur(X, tp2)
101102
case OrType(tp1, tp2) => recur(X, tp1) && recur(X, tp2)
102103
case AnnotatedType(t, an) => recur(X, t)
103104
case _: RefinedType => false
104105
case _ => true
105-
}
106+
})
106107

107108
val res = recur(X.widen, replaceBinderMap.apply(P))
108109

0 commit comments

Comments
 (0)