Skip to content

Commit 700db3c

Browse files
authored
Fix deterministically adding additional interfaces (#20593)
2 parents 1efbb92 + 7500b05 commit 700db3c

File tree

4 files changed

+33
-7
lines changed

4 files changed

+33
-7
lines changed

compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,11 +113,12 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I, val frontendAcce
113113
val directlyInheritedTraits = sym.directlyInheritedTraits
114114
val directlyInheritedTraitsSet = directlyInheritedTraits.toSet
115115
val allBaseClasses = directlyInheritedTraits.iterator.flatMap(_.asClass.baseClasses.drop(1)).toSet
116-
val superCalls = superCallsMap.getOrElse(sym, Set.empty)
117-
val additional = (superCalls -- directlyInheritedTraitsSet).filter(_.is(Trait))
116+
val superCalls = superCallsMap.getOrElse(sym, List.empty)
117+
val superCallsSet = superCalls.toSet
118+
val additional = superCalls.filter(t => !directlyInheritedTraitsSet(t) && t.is(Trait))
118119
// if (additional.nonEmpty)
119120
// println(s"$fullName: adding supertraits $additional")
120-
directlyInheritedTraits.filter(t => !allBaseClasses(t) || superCalls(t)) ++ additional
121+
directlyInheritedTraits.filter(t => !allBaseClasses(t) || superCallsSet(t)) ++ additional
121122
}
122123

123124
val interfaces = classSym.superInterfaces.map(classBTypeFromSymbol)

compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import StdNames.nme
2525
import NameKinds.{LazyBitMapName, LazyLocalName}
2626
import Names.Name
2727

28-
class DottyBackendInterface(val superCallsMap: ReadOnlyMap[Symbol, Set[ClassSymbol]])(using val ctx: Context) {
28+
class DottyBackendInterface(val superCallsMap: ReadOnlyMap[Symbol, List[ClassSymbol]])(using val ctx: Context) {
2929

3030
private val desugared = new java.util.IdentityHashMap[Type, tpd.Select]
3131

compiler/src/dotty/tools/backend/jvm/GenBCode.scala

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,11 @@ class GenBCode extends Phase { self =>
2323

2424
override def isRunnable(using Context) = super.isRunnable && !ctx.usedBestEffortTasty
2525

26-
private val superCallsMap = new MutableSymbolMap[Set[ClassSymbol]]
26+
private val superCallsMap = new MutableSymbolMap[List[ClassSymbol]]
2727
def registerSuperCall(sym: Symbol, calls: ClassSymbol): Unit = {
28-
val old = superCallsMap.getOrElse(sym, Set.empty)
29-
superCallsMap.update(sym, old + calls)
28+
val old = superCallsMap.getOrElse(sym, List.empty)
29+
if (!old.contains(calls))
30+
superCallsMap.update(sym, old :+ calls)
3031
}
3132

3233
private val entryPoints = new mutable.HashSet[String]()

compiler/test/dotty/tools/backend/jvm/DottyBytecodeTests.scala

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1963,6 +1963,30 @@ class DottyBytecodeTests extends DottyBytecodeTest {
19631963
assertSameCode(instructions, expected)
19641964
}
19651965
}
1966+
1967+
/**
1968+
* Test 'additional' imports are generated in deterministic order
1969+
* https://github.com/scala/scala3/issues/20496
1970+
*/
1971+
@Test def deterministicAdditionalImports = {
1972+
val source =
1973+
"""trait Actor:
1974+
| def receive() = ()
1975+
|trait Timers:
1976+
| def timers() = ()
1977+
|abstract class ShardCoordinator extends Actor with Timers
1978+
|class PersistentShardCoordinator extends ShardCoordinator:
1979+
| def foo =
1980+
| super.receive()
1981+
| super.timers()""".stripMargin
1982+
checkBCode(source) { dir =>
1983+
val clsIn = dir.lookupName("PersistentShardCoordinator.class", directory = false).input
1984+
val clsNode = loadClassNode(clsIn)
1985+
1986+
val expected = List("Actor", "Timers")
1987+
assertEquals(expected, clsNode.interfaces.asScala)
1988+
}
1989+
}
19661990
}
19671991

19681992
object invocationReceiversTestCode {

0 commit comments

Comments
 (0)