Skip to content

Commit e0b6f39

Browse files
committed
Fix bug in erasedLub leading to incorrect signatures
Before this commit, the added testcase failed in a strange way: 14 | def bla(foo: Foo) = orElse2(identity).apply(foo) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |value of type <nonsensical><notype></nonsensical> does not take parameters This happened because the TermRef for the apply method had an incorrect signature, therefore its underlying type was NoType. According to the documentation of `erasedLub`, the erasure should be: "a common superclass or trait S of the argument classes, with the following two properties: S is minimal: no other common superclass or trait derives from S] S is last : in the linearization of the first argument type `tp1` there are no minimal common superclasses or traits that come after S. (the reason to pick last is that we prefer classes over traits that way)." I'm not convinced that the implementation satisfies either of these two properties, but this commit at least makes S closer to being minimal by making sure that the last best candidate never derives from it.
1 parent c844809 commit e0b6f39

File tree

2 files changed

+23
-4
lines changed

2 files changed

+23
-4
lines changed

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

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -246,10 +246,14 @@ object TypeErasure {
246246
val cls2 = tp2.classSymbol
247247
def loop(bcs: List[ClassSymbol], bestSoFar: ClassSymbol): ClassSymbol = bcs match {
248248
case bc :: bcs1 =>
249-
if (cls2.derivesFrom(bc))
250-
if (!bc.is(Trait) && bc != defn.AnyClass) bc
251-
else loop(bcs1, if (bestSoFar.derivesFrom(bc)) bestSoFar else bc)
252-
else
249+
if (cls2.derivesFrom(bc)) {
250+
val newBest = if (bestSoFar.derivesFrom(bc)) bestSoFar else bc
251+
252+
if (!bc.is(Trait) && bc != defn.AnyClass)
253+
newBest
254+
else
255+
loop(bcs1, newBest)
256+
} else
253257
loop(bcs1, bestSoFar)
254258
case nil =>
255259
bestSoFar

tests/pos/erased-lub-2.scala

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
trait Foo
2+
3+
trait PF[A, +B] {
4+
def apply(x: A): B
5+
}
6+
7+
object Test {
8+
def orElse2[A1, B1 >: Foo](that: PF[A1, B1]): PF[A1, B1] = ???
9+
10+
def identity[E]: PF[E, E] = ???
11+
12+
def foo: PF[Foo, Foo] = ???
13+
14+
def bla(foo: Foo) = orElse2(identity).apply(foo)
15+
}

0 commit comments

Comments
 (0)