Skip to content

Commit 347a3aa

Browse files
committed
Fix baseClasses computation of AndTypes
List union is clearly wrong, as it is simply the same as ++.
1 parent 8ddfcaf commit 347a3aa

File tree

2 files changed

+28
-27
lines changed

2 files changed

+28
-27
lines changed

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

Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1407,32 +1407,13 @@ object SymDenotations {
14071407
baseData._2
14081408

14091409
def computeBaseData(implicit onBehalf: BaseData, ctx: Context): (List[ClassSymbol], BaseClassSet) = {
1410-
val seen = new BaseClassSetBuilder
1411-
def addBaseClasses(bcs: List[ClassSymbol], to: List[ClassSymbol])
1412-
: List[ClassSymbol] = bcs match {
1413-
case bc :: bcs1 =>
1414-
val bcs1added = addBaseClasses(bcs1, to)
1415-
if (seen contains bc) bcs1added
1416-
else {
1417-
seen.add(bc)
1418-
bc :: bcs1added
1419-
}
1420-
case nil =>
1421-
to
1422-
}
1423-
def addParentBaseClasses(ps: List[TypeRef], to: List[ClassSymbol]): List[ClassSymbol] = ps match {
1424-
case p :: ps1 =>
1425-
addParentBaseClasses(ps1,
1426-
addBaseClasses(p.symbol.asClass.baseClasses, to))
1427-
case nil =>
1428-
to
1429-
}
14301410
def emptyParentsExpected =
14311411
is(Package) || (symbol == defn.AnyClass) || ctx.erasedTypes && (symbol == defn.ObjectClass)
14321412
if (classParents.isEmpty && !emptyParentsExpected)
14331413
onBehalf.signalProvisional()
1434-
(classSymbol :: addParentBaseClasses(classParents, Nil),
1435-
seen.result)
1414+
val builder = new BaseDataBuilder
1415+
for (p <- classParents) builder.addAll(p.symbol.asClass.baseClasses)
1416+
(classSymbol :: builder.baseClasses, builder.baseClassSet)
14361417
}
14371418

14381419
final override def derivesFrom(base: Symbol)(implicit ctx: Context): Boolean =
@@ -2096,7 +2077,9 @@ object SymDenotations {
20962077
def contains(sym: Symbol): Boolean = contains(sym, classIds.length)
20972078
}
20982079

2099-
private class BaseClassSetBuilder {
2080+
/** A class to combine base data from parent types */
2081+
class BaseDataBuilder {
2082+
private var classes: List[ClassSymbol] = Nil
21002083
private var classIds = new Array[Int](32)
21012084
private var length = 0
21022085

@@ -2106,19 +2089,34 @@ object SymDenotations {
21062089
classIds = classIds1
21072090
}
21082091

2109-
def contains(sym: Symbol): Boolean =
2092+
private def contains(sym: Symbol): Boolean =
21102093
new BaseClassSet(classIds).contains(sym, length)
21112094

2112-
def add(sym: Symbol): Unit = {
2095+
private def add(sym: Symbol): Unit = {
21132096
if (length == classIds.length) resize(length * 2)
21142097
classIds(length) = sym.id
21152098
length += 1
21162099
}
21172100

2118-
def result = {
2101+
def addAll(bcs: List[ClassSymbol]): this.type = {
2102+
bcs match {
2103+
case bc :: bcs1 =>
2104+
addAll(bcs1)
2105+
if (!contains(bc)) {
2106+
add(bc)
2107+
classes = bc :: classes
2108+
}
2109+
case nil =>
2110+
}
2111+
this
2112+
}
2113+
2114+
def baseClassSet = {
21192115
if (length != classIds.length) resize(length)
21202116
new BaseClassSet(classIds)
21212117
}
2118+
2119+
def baseClasses: List[ClassSymbol] = classes
21222120
}
21232121

21242122
@sharable private var indent = 0 // for completions printing

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,10 @@ object Types {
394394
case tp: ClassInfo =>
395395
tp.cls.baseClasses
396396
case AndType(tp1, tp2) =>
397-
tp1.baseClasses union tp2.baseClasses
397+
(new BaseDataBuilder)
398+
.addAll(tp1.baseClasses)
399+
.addAll(tp2.baseClasses)
400+
.baseClasses
398401
case OrType(tp1, tp2) =>
399402
tp1.baseClasses intersect tp2.baseClasses
400403
case _ => Nil

0 commit comments

Comments
 (0)