Skip to content

Commit 5c5ab17

Browse files
committed
Fix #8662: Fix desugaring of try-catches that are partial functions
1 parent 3d26c53 commit 5c5ab17

File tree

2 files changed

+40
-6
lines changed

2 files changed

+40
-6
lines changed

compiler/src/dotty/tools/dotc/ast/Desugar.scala

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1612,6 +1612,17 @@ object desugar {
16121612
EmptyTree
16131613
}
16141614

1615+
def makeTryCase(handlerFun: Tree): CaseDef =
1616+
val excId = Ident(nme.DEFAULT_EXCEPTION_NAME)
1617+
val tmpName = UniqueName.fresh()
1618+
val tmpId = Ident(tmpName)
1619+
val init = ValDef(tmpName, TypeTree(), handlerFun)
1620+
val test = If(
1621+
Apply(Select(tmpId, nme.isDefinedAt), excId),
1622+
Apply(Select(tmpId, nme.apply), excId),
1623+
Throw(excId))
1624+
CaseDef(excId, EmptyTree, Block(init :: Nil, test))
1625+
16151626
// begin desugar
16161627

16171628
// Special case for `Parens` desugaring: unlike all the desugarings below,
@@ -1677,14 +1688,10 @@ object desugar {
16771688
val pats1 = if (tpt.isEmpty) pats else pats map (Typed(_, tpt))
16781689
flatTree(pats1 map (makePatDef(tree, mods, _, rhs)))
16791690
case ParsedTry(body, handler, finalizer) =>
1680-
handler match {
1691+
handler match
16811692
case Match(EmptyTree, cases) => Try(body, cases, finalizer)
16821693
case EmptyTree => Try(body, Nil, finalizer)
1683-
case _ =>
1684-
Try(body,
1685-
List(CaseDef(Ident(nme.DEFAULT_EXCEPTION_NAME), EmptyTree, Apply(handler, Ident(nme.DEFAULT_EXCEPTION_NAME)))),
1686-
finalizer)
1687-
}
1694+
case _ => Try(body, makeTryCase(handler) :: Nil, finalizer)
16881695
}
16891696
desugared.withSpan(tree.span)
16901697
}

tests/run/i8662.scala

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
object Main {
2+
class EThrow extends Exception
3+
class ECatch extends Exception
4+
5+
def ok(): Unit =
6+
try throw new EThrow
7+
catch { case _: ECatch => }
8+
9+
def notOk(): Unit = {
10+
val pf: PartialFunction[Throwable, Unit] = {
11+
case e: ECatch =>
12+
}
13+
try throw new EThrow
14+
catch pf
15+
}
16+
17+
def test(f: => Unit): Unit =
18+
try f catch {
19+
case _: EThrow => println("OK")
20+
// case e: Throwable => println("! expect an EThrow but got " + e.getClass)
21+
}
22+
23+
def main(args: Array[String]): Unit = {
24+
test { ok() }
25+
test { notOk() }
26+
}
27+
}

0 commit comments

Comments
 (0)