Skip to content

Commit cb7e494

Browse files
committed
Fix regression in phase assembly with consecutive runsRightAfter
If a phase `runsRightAfter` a phase that itself has been merged into `Node` of the phase that _it_ `runsRightAfter`, we need to find that `Node` to merge into.
1 parent f287790 commit cb7e494

File tree

2 files changed

+47
-2
lines changed

2 files changed

+47
-2
lines changed

src/compiler/scala/tools/nsc/PhaseAssembly.scala

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,11 @@ trait PhaseAssembly {
111111
for (node <- nodes.valuesIterator.toList) {
112112
val hardBefores = node.before.iterator.filter(_.hard).toList
113113
for (hl <- hardBefores) {
114-
node.phaseobj = Some(node.phaseobj.get ++ hl.frm.phaseobj.get)
115-
node.before = hl.frm.before
114+
val effectiveNode: Node = if (nodes.contains(node.name)) node else {
115+
nodes.find(_._2.phaseobj.exists(_.exists(_.phaseName == node.name))).get._2
116+
}
117+
effectiveNode.phaseobj = Some(effectiveNode.phaseobj.get ++ hl.frm.phaseobj.get)
118+
effectiveNode.before = hl.frm.before
116119
nodes -= hl.frm.phasename
117120
edges -= hl
118121
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Scala (https://www.scala-lang.org)
3+
*
4+
* Copyright EPFL and Lightbend, Inc.
5+
*
6+
* Licensed under Apache License 2.0
7+
* (http://www.apache.org/licenses/LICENSE-2.0).
8+
*
9+
* See the NOTICE file distributed with this work for
10+
* additional information regarding copyright ownership.
11+
*/
12+
13+
package scala.tools.nsc
14+
15+
import org.junit.Assert.assertEquals
16+
import org.junit.Test
17+
18+
class PhaseAssemblyTest {
19+
@Test
20+
def multipleRunsRightAfter(): Unit = {
21+
val global = new Global(new Settings)
22+
case class component[G <: Global with Singleton](global: G, phaseName: String, override val runsRightAfter: Option[String], override val runsAfter: List[String], override val runsBefore: List[String]) extends SubComponent {
23+
override def newPhase(prev: Phase): Phase = ???
24+
}
25+
val N = 16
26+
val random = new scala.util.Random(123502L)
27+
val names = Array.fill(N)("phase_" + random.nextInt(1024))
28+
val parserAndTerminal = List(
29+
component(global, "parser", None, Nil, Nil),
30+
component(global,"terminal", None, Nil, List(N.toString))
31+
)
32+
val components = List.tabulate(N)(i => component(global, names(i), Some(if (i == 0) "parser" else names(i - 1)), Nil, List("terminal"))) ::: parserAndTerminal
33+
34+
val graph = global.phasesSetToDepGraph(components.reverse)
35+
graph.removeDanglingNodes()
36+
graph.collapseHardLinks()
37+
graph.assignLevelsAndDetectCycles(graph.getNodeByPhase("parser"))
38+
val result: List[String] =graph.compilerPhaseList().map(_.phaseName).filter(_.startsWith("phase_"))
39+
assertEquals(names.toList, result)
40+
}
41+
42+
}

0 commit comments

Comments
 (0)