Skip to content

Commit

Permalink
Merge pull request #5082 from dotty-staging/small-pattern-match-optim…
Browse files Browse the repository at this point in the history
…ization

Do not generate Return nodes for throw expressions
  • Loading branch information
nicolasstucki authored Sep 5, 2018
2 parents e02c785 + 2873a73 commit eda6b0c
Show file tree
Hide file tree
Showing 2 changed files with 51 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.tpe <:< defn.NothingType) tree // For example MatchError
else Return(tree, ref(resultLabel))
}
}

Expand Down
49 changes: 49 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,53 @@ class TestBCode extends DottyBytecodeTest {
}
}

@Test def returnThrowInPatternMatch = {
val source =
"""class Test {
| def test(a: Any): Int = {
| a match {
| case _: Test => ???
| }
| }
|}
""".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(11)),
VarOp(Opcodes.ALOAD, 2),
TypeOp(Opcodes.CHECKCAST, "Test"),
VarOp(Opcodes.ASTORE, 3),
Field(Opcodes.GETSTATIC, "scala/Predef$", "MODULE$", "Lscala/Predef$;"),
Invoke(Opcodes.INVOKEVIRTUAL, "scala/Predef$", "$qmark$qmark$qmark", "()Lscala/runtime/Nothing$;", false),
Op(Opcodes.ATHROW),
Label(11),
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(18),
FrameEntry(0, List(), List("java/lang/Throwable")),
Op(Opcodes.ATHROW),
Label(21),
FrameEntry(4, List(), List("java/lang/Throwable")),
Op(Opcodes.ATHROW)
)
assert(instructions == expected,
"`test` was not properly generated\n" + diffInstructions(instructions, expected))

}
}

}

0 comments on commit eda6b0c

Please sign in to comment.