Skip to content

Commit 2c1e646

Browse files
authored
Merge pull request #2975 from dotty-staging/fix-hk-isRef
Fix #2971: Soudness issue with variance and higher kinded types
2 parents 8b8baba + f70ca09 commit 2c1e646

File tree

3 files changed

+27
-1
lines changed

3 files changed

+27
-1
lines changed

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,9 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
413413
// of an `AndType` can lead to a cascade of subtyping checks
414414
// This twist is needed to make collection/generic/ParFactory.scala compile
415415
fourthTry(tp1, tp2) || compareRefinedSlow
416+
case tp1: HKTypeLambda =>
417+
// HKTypeLambdas do not have members.
418+
fourthTry(tp1, tp2)
416419
case _ =>
417420
compareRefinedSlow || fourthTry(tp1, tp2)
418421
}

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,10 @@ object Types {
132132
case _ => this1.symbol eq sym
133133
}
134134
case this1: RefinedOrRecType => this1.parent.isRef(sym)
135-
case this1: HKApply => this1.superType.isRef(sym)
135+
case this1: HKApply =>
136+
val this2 = this1.dealias
137+
if (this2 ne this1) this2.isRef(sym)
138+
else this1.underlying.isRef(sym)
136139
case _ => false
137140
}
138141

tests/neg/i2971.scala

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
case class Foo[+X[_]](will: X[Int]) {
2+
def foo[Y[_]](right: Foo[Y]) = Foo.doFoo(this, right)
3+
}
4+
5+
class A[X] { def crash = true }
6+
class B[X]
7+
8+
object Foo {
9+
def doFoo[X[_]](left: Foo[X], right: Foo[X]): Foo[X] = right
10+
11+
def main(args: Array[String]): Unit = {
12+
val fooA = Foo(new A[Int])
13+
val fooB = Foo(new B[Int])
14+
// The type for this is inferred correctly to Foo[A|B]
15+
val fine = doFoo(fooA, fooB)
16+
// This throws a ClassCastException because fooB isn't a Foo[A]
17+
val oops: Foo[A] = fooA.foo(fooB) // error: found: Foo[B], required: Foo[A]
18+
println(oops.will.crash)
19+
}
20+
}

0 commit comments

Comments
 (0)