Skip to content

Commit

Permalink
Do not generate Return nodes for throw expressions
Browse files Browse the repository at this point in the history
Namely throw MatchError
  • Loading branch information
nicolasstucki committed Sep 5, 2018
1 parent e02c785 commit f88c09b
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 1 deletion.
3 changes: 2 additions & 1 deletion compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala
Original file line number Diff line number Diff line change
Expand Up @@ -839,7 +839,8 @@ object PatternMatcher {
default
}
case ResultPlan(tree) =>
Return(tree, ref(resultLabel))
if (tree.symbol eq defn.throwMethod) tree // Namely MatchError
else Return(tree, ref(resultLabel))
}
}

Expand Down
45 changes: 45 additions & 0 deletions compiler/test/dotty/tools/backend/jvm/DottyBytecodeTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -401,4 +401,49 @@ class TestBCode extends DottyBytecodeTest {
}
}

@Test def returnThrowInPatternMatch = {
val source =
"""class Test {
| def test(a: Any): Int = {
| a match {
| case _: Test => 1
| }
| }
|}
""".stripMargin

checkBCode(source) { dir =>
val moduleIn = dir.lookupName("Test.class", directory = false)
val moduleNode = loadClassNode(moduleIn.input)
val method = getMethod(moduleNode, "test")

val instructions = instructionsFromMethod(method)
val expected = List(
VarOp(Opcodes.ALOAD, 1),
VarOp(Opcodes.ASTORE, 2),
VarOp(Opcodes.ALOAD, 2),
TypeOp(Opcodes.INSTANCEOF, "Test"),
Jump(Opcodes.IFEQ, Label(10)),
VarOp(Opcodes.ALOAD, 2),
TypeOp(Opcodes.CHECKCAST, "Test"),
VarOp(Opcodes.ASTORE, 3),
Op(Opcodes.ICONST_1),
Jump(Opcodes.GOTO, Label(17)),
Label(10),
FrameEntry(1, List("java/lang/Object"), List()),
TypeOp(Opcodes.NEW, "scala/MatchError"),
Op(Opcodes.DUP),
VarOp(Opcodes.ALOAD, 2),
Invoke(Opcodes.INVOKESPECIAL, "scala/MatchError", "<init>", "(Ljava/lang/Object;)V", false),
Op(Opcodes.ATHROW),
Label(17),
FrameEntry(0, List("Test", "java/lang/Object", "java/lang/Object", "Test"), List(1)),
Op(Opcodes.IRETURN)
)
assert(instructions == expected,
"`test` was not properly generated\n" + diffInstructions(instructions, expected))

}
}

}

0 comments on commit f88c09b

Please sign in to comment.