-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refine handling of CanThrow capabilities #13866
Changes from 3 commits
d987b5a
abffac2
2c5613c
6381d9d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
-- Error: tests/neg/i13846.scala:3:22 ---------------------------------------------------------------------------------- | ||
3 |def foo(): Int throws ArithmeticException = 1 / 0 // error | ||
| ^^^^^^^^^^^^^^^^^^^ | ||
| throws clause cannot be defined for RuntimeException | ||
-- Error: tests/neg/i13846.scala:7:9 ----------------------------------------------------------------------------------- | ||
7 | foo() // error | ||
| ^ | ||
| The capability to throw exception ArithmeticException is missing. | ||
| The capability can be provided by one of the following: | ||
| - A using clause `(using CanThrow[ArithmeticException])` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we don't synthesize instances of |
||
| - A `throws` clause in a result type such as `X throws ArithmeticException` | ||
| - an enclosing `try` that catches ArithmeticException | ||
| | ||
| The following import might fix the problem: | ||
| | ||
| import unsafeExceptions.canThrowAny | ||
| |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import language.experimental.saferExceptions | ||
|
||
def foo(): Int throws ArithmeticException = 1 / 0 // error | ||
|
||
def test(): Unit = | ||
try | ||
foo() // error | ||
catch | ||
case _: ArithmeticException => println("Caught") |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
-- Error: tests/neg/i13849.scala:16:11 --------------------------------------------------------------------------------- | ||
16 | case _: Ex if false => println("Caught") // error | ||
| ^^^^^ | ||
| Implementation restriction: cannot generate CanThrow capability for this kind of catch. | ||
| CanThrow capabilities can only be generated if no pattern guard is given. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import annotation.experimental | ||
import language.experimental.saferExceptions | ||
|
||
@experimental | ||
case class Ex(i: Int) extends Exception(s"Exception: $i") | ||
|
||
@experimental | ||
def foo(): Unit throws Ex = throw Ex(1) | ||
|
||
@experimental | ||
object Main: | ||
def main(args: Array[String]): Unit = | ||
try | ||
foo() | ||
catch | ||
case _: Ex if false => println("Caught") // error |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
-- Error: tests/neg/i13864.scala:11:9 ---------------------------------------------------------------------------------- | ||
11 | case Ex(i: Int) => println("Caught an Int") // error | ||
| ^^^^^^^^^^ | ||
| Implementation restriction: cannot generate CanThrow capability for this kind of catch. | ||
| CanThrow capabilities can only be generated for cases of the form `ex: T` where `T` is fully defined. | ||
-- Error: tests/neg/i13864.scala:9:10 ---------------------------------------------------------------------------------- | ||
9 | foo(1) // error | ||
| ^ | ||
| The capability to throw exception Ex[Int] is missing. | ||
| The capability can be provided by one of the following: | ||
| - A using clause `(using CanThrow[Ex[Int]])` | ||
| - A `throws` clause in a result type such as `X throws Ex[Int]` | ||
| - an enclosing `try` that catches Ex[Int] | ||
| | ||
| The following import might fix the problem: | ||
| | ||
| import unsafeExceptions.canThrowAny | ||
| |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import language.experimental.saferExceptions | ||
|
||
case class Ex[A](a: A) extends Exception(s"Ex: $a") | ||
|
||
def foo[A](a: A): Unit throws Ex[A] = throw new Ex(a) | ||
|
||
def test(): Unit = | ||
try | ||
foo(1) // error | ||
catch | ||
case Ex(i: Int) => println("Caught an Int") // error |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there really a gain in explicitly preventing users from declaring throwing
RuntimeException
s? And even if we disallow methods likethen
will be still valid, right? So this somehow defeats the purpose IMHO
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We won't generate a capability for it, so it's better to communicate that early. But I think ding this for throws clauses is enough. I don't want to start imposing restrictions on general implicit parameters.