Skip to content

Commit 952b928

Browse files
authored
Don't re-balance AndTypes arising from supertypes (#20400)
#20284 started breaking since we now balance AndTypes to avoid performance drops. But (re-)balancing an AndType interferes with the logic that determines which symbol is referred by a super select. This is fixed by two changes: - Form types of super with `AndType` instead of `&` - Don't simplify types of super since that would rebalance the underlying AndTypes. Fixes #20284
2 parents 7bdeb0b + f0560b2 commit 952b928

File tree

4 files changed

+74
-1
lines changed

4 files changed

+74
-1
lines changed

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

+4
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,10 @@ object TypeOps:
190190
// Mapping over a skolem creates a new skolem which by definition won't
191191
// be =:= to the original one.
192192
tp
193+
case tp: SuperType =>
194+
// Mapping a supertype might re-balance an AndType which is not permitted since
195+
// we need the original order of parents for current super resolution.
196+
tp
193197
case _ =>
194198
mapOver
195199
}

compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ trait TypeAssigner {
261261
else if (ctx.erasedTypes) cls.info.firstParent.typeConstructor
262262
else {
263263
val ps = cls.classInfo.parents
264-
if (ps.isEmpty) defn.AnyType else ps.reduceLeft((x: Type, y: Type) => x & y)
264+
if ps.isEmpty then defn.AnyType else ps.reduceLeft(AndType(_, _))
265265
}
266266
SuperType(cls.thisType, owntype)
267267

tests/run/i20284.check

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
Test 1
2+
D
3+
B
4+
C
5+
A
6+
Test 2
7+
D
8+
B
9+
C
10+
A
11+
Test 3
12+
D
13+
B
14+
C
15+
A

tests/run/i20284.scala

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
trait A {
2+
def print: Unit = println("A")
3+
}
4+
5+
trait B extends A {
6+
override def print: Unit = {
7+
println("B")
8+
super.print
9+
}
10+
}
11+
12+
trait C extends A {
13+
override def print: Unit = {
14+
println("C")
15+
super.print
16+
}
17+
}
18+
19+
trait D extends B {
20+
override def print: Unit = {
21+
println("D")
22+
super.print
23+
}
24+
}
25+
26+
trait BB extends B
27+
28+
trait X
29+
trait Y
30+
trait Z
31+
32+
class Test1 extends C with B with BB with D with X with Y with Z:
33+
override def print: Unit = {
34+
println("Test 1")
35+
super.print
36+
}
37+
38+
class Test2 extends C with B with BB with D with X with Y {
39+
override def print: Unit = {
40+
println("Test 2")
41+
super.print
42+
}
43+
}
44+
45+
class Test3 extends X with Y with Z with C with B with BB with D {
46+
override def print: Unit = {
47+
println("Test 3")
48+
super.print
49+
}
50+
}
51+
@main def Test =
52+
new Test1().print
53+
new Test2().print
54+
new Test3().print

0 commit comments

Comments
 (0)