Skip to content

Commit d987b5a

Browse files
committed
Disallow throws clauses over RuntimeExceptions
Fixes #13846
1 parent 29f0374 commit d987b5a

File tree

3 files changed

+35
-3
lines changed

3 files changed

+35
-3
lines changed

compiler/src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1936,14 +1936,20 @@ class Typer extends Namer
19361936
}
19371937
var checkedArgs = preCheckKinds(args1, paramBounds)
19381938
// check that arguments conform to bounds is done in phase PostTyper
1939-
if (tpt1.symbol == defn.andType)
1939+
val tycon = tpt1.symbol
1940+
if (tycon == defn.andType)
19401941
checkedArgs = checkedArgs.mapconserve(arg =>
19411942
checkSimpleKinded(checkNoWildcard(arg)))
1942-
else if (tpt1.symbol == defn.orType)
1943+
else if (tycon == defn.orType)
19431944
checkedArgs = checkedArgs.mapconserve(arg =>
19441945
checkSimpleKinded(checkNoWildcard(arg)))
1946+
else if tycon == defn.throwsAlias
1947+
&& checkedArgs.length == 2
1948+
&& checkedArgs(1).tpe.derivesFrom(defn.RuntimeExceptionClass)
1949+
then
1950+
report.error(em"throws clause cannot be defined for RuntimeException", checkedArgs(1).srcPos)
19451951
else if (ctx.isJava)
1946-
if (tpt1.symbol eq defn.ArrayClass) then
1952+
if tycon eq defn.ArrayClass then
19471953
checkedArgs match {
19481954
case List(arg) =>
19491955
val elemtp = arg.tpe.translateJavaArrayElementType

tests/neg/i13846.check

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
-- Error: tests/neg/i13846.scala:3:22 ----------------------------------------------------------------------------------
2+
3 |def foo(): Int throws ArithmeticException = 1 / 0 // error
3+
| ^^^^^^^^^^^^^^^^^^^
4+
| throws clause cannot be defined for RuntimeException
5+
-- Error: tests/neg/i13846.scala:7:9 -----------------------------------------------------------------------------------
6+
7 | foo() // error
7+
| ^
8+
| The capability to throw exception ArithmeticException is missing.
9+
| The capability can be provided by one of the following:
10+
| - A using clause `(using CanThrow[ArithmeticException])`
11+
| - A `throws` clause in a result type such as `X throws ArithmeticException`
12+
| - an enclosing `try` that catches ArithmeticException
13+
|
14+
| The following import might fix the problem:
15+
|
16+
| import unsafeExceptions.canThrowAny
17+
|

tests/neg/i13846.scala

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import language.experimental.saferExceptions
2+
3+
def foo(): Int throws ArithmeticException = 1 / 0 // error
4+
5+
def test(): Unit =
6+
try
7+
foo() // error
8+
catch
9+
case _: ArithmeticException => println("Caught")

0 commit comments

Comments
 (0)