Skip to content

Commit 137431b

Browse files
committed
Fix #2971: Soudness issue with variance and higher kinded types
We shouldn't use `HKApply#superType` in `isRef`, because this means taking the upper bound of abstract type constructors.
1 parent de19138 commit 137431b

File tree

2 files changed

+21
-1
lines changed

2 files changed

+21
-1
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ 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 => this1.underlying.isRef(sym)
136136
case _ => false
137137
}
138138

tests/pos/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)