Skip to content

Commit cf38a52

Browse files
authored
Merge pull request scala#6459 from lrytz/merge-2.12-to-2.13-mar-22
Merge 2.12 to 2.13 mar 22
2 parents ea63368 + a4916bc commit cf38a52

File tree

8 files changed

+68
-6
lines changed

8 files changed

+68
-6
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ jobs:
4848
- rm -rf build/ # ensure we resolve from artifactory
4949
- buildModules
5050
- buildQuick clean publish
51-
- set | grep -E '^updatedModuleVersions=|^SCALA_VER=|^publishToSonatype=' > build/env
51+
- set | grep -E '^SCALA_VER=|^SCALA_BINARY_VER=|^scalaVersionTasks=|^XML_VER=|^PARTEST_VER=|^SCALACHECK_VER=|^XML_BUILT=|^PARTEST_BUILT=|^SCALACHECK_REF=|^updatedModuleVersions=|^publishToSonatype=' > build/env
5252
- cat build/env
5353

5454
# this builds the spec using jekyll

scripts/jobs/integrate/bootstrap

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@ sbtArgs="-ivy $IVY2_DIR -Dsbt.override.build.repos=true -Dsbt.repository.config=
99

1010
source scripts/bootstrap_fun
1111

12+
generateRepositoriesConfig $integrationRepoUrl
13+
1214
determineScalaVersion
1315
deriveModuleVersions
1416

15-
generateRepositoriesConfig $integrationRepoUrl
16-
1717
removeExistingBuilds $integrationRepoUrl
1818
clearIvyCache
1919

src/compiler/scala/tools/nsc/backend/jvm/ClassfileWriters.scala

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,10 @@ abstract class ClassfileWriters {
143143
try Files.createDirectories(parent, noAttributes: _*)
144144
catch {
145145
case e: FileAlreadyExistsException =>
146-
throw new FileConflictException(s"Can't create directory $parent; there is an existing (non-directory) file in its path", e)
146+
// `createDirectories` reports this exception if `parent` is an existing symlink to a directory
147+
// but that's fine for us (and common enough, `scalac -d /tmp` on mac targets symlink).
148+
if (!Files.isDirectory(parent))
149+
throw new FileConflictException(s"Can't create directory $parent; there is an existing (non-directory) file in its path", e)
147150
}
148151
builtPaths.put(baseDir, TRUE)
149152
var current = parent

src/compiler/scala/tools/nsc/backend/jvm/opt/BytecodeUtils.scala

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,15 @@ object BytecodeUtils {
141141
else previousExecutableInstruction(prev, stopBefore)
142142
}
143143

144+
@tailrec def previousLineNumber(insn: AbstractInsnNode): Option[Int] = {
145+
val prev = insn.getPrevious
146+
prev match {
147+
case null => None
148+
case line: LineNumberNode => Some(line.line)
149+
case _ => previousLineNumber(prev)
150+
}
151+
}
152+
144153
@tailrec def nextExecutableInstruction(insn: AbstractInsnNode, alsoKeep: AbstractInsnNode => Boolean = Set()): Option[AbstractInsnNode] = {
145154
val next = insn.getNext
146155
if (next == null || isExecutable(next) || alsoKeep(next)) Option(next)

src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,19 @@ abstract class Inliner {
440440
// label for the exit of the inlined functions. xRETURNs are replaced by GOTOs to this label.
441441
val postCallLabel = newLabelNode
442442
clonedInstructions.add(postCallLabel)
443+
if (sameSourceFile) {
444+
BytecodeUtils.previousLineNumber(callsiteInstruction) match {
445+
case Some(line) =>
446+
BytecodeUtils.nextExecutableInstruction(callsiteInstruction).flatMap(BytecodeUtils.previousLineNumber) match {
447+
case Some(line1) =>
448+
if (line == line1)
449+
// SD-479 code follows on the same line, restore the line number
450+
clonedInstructions.add(new LineNumberNode(line, postCallLabel))
451+
case None =>
452+
}
453+
case None =>
454+
}
455+
}
443456

444457
// replace xRETURNs:
445458
// - store the return value (if any)

src/compiler/scala/tools/nsc/backend/jvm/opt/LocalOpt.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,7 @@ abstract class LocalOpt {
524524
case i: IincInsnNode if isLive =>
525525
maxLocals = math.max(maxLocals, i.`var` + 1)
526526

527+
case _: LineNumberNode =>
527528
case _ =>
528529
if (!isLive || insn.getOpcode == NOP) {
529530
// Instruction iterators allow removing during iteration.

test/junit/scala/tools/nsc/backend/jvm/opt/InlinerTest.scala

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1551,11 +1551,11 @@ class InlinerTest extends BytecodeTesting {
15511551

15521552
assertSameCode(is("t2"), List(
15531553
Label(0), LineNumber(3, Label(0)), VarOp(ALOAD, 0), Invoke(INVOKEVIRTUAL, "B", "fx", "()V", false),
1554-
Label(4), LineNumber(4, Label(4)), Op(ICONST_1), Op(IRETURN), Label(8)))
1554+
Label(4), LineNumber(4, Label(4)), Op(ICONST_1), Label(7), LineNumber(13, Label(7)), Op(IRETURN), Label(10)))
15551555

15561556
assertSameCode(is("t3"), List(
15571557
Label(0), LineNumber(9, Label(0)), VarOp(ALOAD, 0), Invoke(INVOKEVIRTUAL, "C", "fx", "()V", false),
1558-
Label(4), LineNumber(10, Label(4)), Op(ICONST_1), Op(IRETURN), Label(8)))
1558+
Label(4), LineNumber(10, Label(4)), Op(ICONST_1), Label(7), LineNumber(14, Label(7)), Op(IRETURN), Label(10)))
15591559
}
15601560

15611561
@Test
@@ -1754,4 +1754,22 @@ class InlinerTest extends BytecodeTesting {
17541754
assertDoesNotInvoke(i, "f")
17551755
assertInvoke(i, "T", "T$_setter_$x_$eq")
17561756
}
1757+
1758+
@Test
1759+
def sd479_same_unit_inlining_line_number(): Unit = {
1760+
val code =
1761+
"""class Test {
1762+
| @inline final def foo(b: Boolean): String = {
1763+
| "foo"
1764+
| }
1765+
|
1766+
| def bar(a: AnyRef, b: Boolean): AnyRef = {
1767+
| foo(b); a.toString // line 7
1768+
| }
1769+
|}
1770+
""".stripMargin
1771+
val List(t) = compileClasses(code)
1772+
val i = getMethod(t, "bar")
1773+
assertSameCode(i.instructions, List(Label(0), LineNumber(7, Label(0)), VarOp(ALOAD, 1), Invoke(INVOKEVIRTUAL, "java/lang/Object", "toString", "()Ljava/lang/String;", false), Op(ARETURN), Label(5)))
1774+
}
17571775
}

test/junit/scala/tools/nsc/backend/jvm/opt/UnreachableCodeTest.scala

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import org.junit.runner.RunWith
88
import org.junit.runners.JUnit4
99

1010
import scala.tools.asm.Opcodes._
11+
import scala.tools.asm.tree.ClassNode
1112
import scala.tools.partest.ASMConverters._
1213
import scala.tools.testing.AssertUtil._
1314
import scala.tools.testing.BytecodeTesting._
@@ -245,4 +246,21 @@ class UnreachableCodeTest extends ClearAfterClass {
245246
assertSameSummary(getMethod(cDCE, "t3"), List(ALOAD, NEW, DUP, LDC, "<init>", ATHROW))
246247
assertSameSummary(getMethod(cDCE, "t4"), List(ALOAD, ALOAD, "nt", ATHROW))
247248
}
249+
250+
@Test
251+
def patmatDefaultLineNumber(): Unit = {
252+
val code =
253+
"""class Test {
254+
| def test = (this: AnyRef) match {
255+
| case _: String =>
256+
| "line4" // the synthetic `throw new MatchError` used to be positioned, here, despite the fact that patmat positions it at line 3.
257+
| }
258+
|}
259+
|""".stripMargin
260+
val test: ClassNode = dceCompiler.compileClass(code)
261+
val i = getAsmMethod(test, "test")
262+
val instr = findInstrs(i, "NEW scala/MatchError").head
263+
val lineNumber = BytecodeUtils.previousLineNumber(instr)
264+
assertEquals(Some(2), lineNumber)
265+
}
248266
}

0 commit comments

Comments
 (0)