summaryrefslogtreecommitdiff
path: root/test/files/pos/t6479.scala
Commit message (Collapse)AuthorAgeFilesLines
* SI-6479 Don't lift try exprs in label arguments.Jason Zaugg2013-01-131-0/+56
The new pattern matcher uses label jumps to GOTO the next case. Uncurry treated these like regular method arguments, and performed the liftedTree() transformation, which ensures that try expressions are only used in a statement position. Even try in statement position of a block used as such an argument are subject to the same transform. This transform stems from the JVM limitation, that try/catch does not leave a value on the stack. See b194446. This commit changes Uncurry to avoid this transform for arguments to label jumps. This avoids needlessly indirect code, and enables tail call elimination in more cases. As an example, Scala 2.10.0 transforms the last method of the enclosed test case to: try { case <synthetic> val x1: Int = 1; case5(){ if (2.==(x1)) { val x2: Int = x1; matchEnd4({ { def liftedTree2(): Unit = try { throw new scala.runtime.NonLocalReturnControl[Unit](nonLocalReturnKey1, ()) } catch { case (e @ (_: ClassNotFoundException)) => () }; liftedTree2() }; TailrecAfterTryCatch.this.bad() }) } else case6() }; case6(){ matchEnd4(throw new MatchError(x1)) }; matchEnd4(x: Unit){ x } } catch { case (ex @ (_: scala.runtime.NonLocalReturnControl[Unit @unchecked])) => if (ex.key().eq(nonLocalReturnKey1)) ex.value() else throw ex } After this patch: @scala.annotation.tailrec final def bad(): Unit = { case <synthetic> val x1: Int = 1; case5(){ if (2.==(x1)) { <synthetic> val x2: Int = x1; matchEnd4({ try { return () } catch { case (e @ (_: ClassNotFoundException)) => () }; TailrecAfterTryCatch.this.bad() }) } else case6() }; case6(){ matchEnd4(throw new MatchError(x1)) }; matchEnd4(x: Unit){ x } }