Skip to content

Commit 99d7f16

Browse files
committed
Backport new ControlThrowable
Backport `scala.util.control.ControlThrowable` from 2.13 (which does not suppress exceptions or have a stack trace) as `scala.util.control.compat.ControlThrowable` (it still extends previous Scala versions' `scala.util.control.ControlThrowable`).
1 parent a6e9cb1 commit 99d7f16

File tree

3 files changed

+76
-0
lines changed

3 files changed

+76
-0
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* Scala (https://www.scala-lang.org)
3+
*
4+
* Copyright EPFL and Lightbend, Inc.
5+
*
6+
* Licensed under Apache License 2.0
7+
* (http://www.apache.org/licenses/LICENSE-2.0).
8+
*
9+
* See the NOTICE file distributed with this work for
10+
* additional information regarding copyright ownership.
11+
*/
12+
package scala.util.control.compat
13+
14+
/** A parent class for throwable objects intended for flow control.
15+
*
16+
* Instances of `ControlThrowable` should not normally be caught.
17+
*
18+
* As a convenience, `NonFatal` does not match `ControlThrowable`.
19+
*
20+
* {{{
21+
* import scala.util.control.{Breaks, NonFatal}, Breaks.{break, breakable}
22+
*
23+
* breakable {
24+
* for (v <- values) {
25+
* try {
26+
* if (p(v)) break
27+
* else ???
28+
* } catch {
29+
* case NonFatal(t) => log(t) // can't catch a break
30+
* }
31+
* }
32+
* }
33+
* }}}
34+
*
35+
* Suppression is disabled, because flow control should not suppress
36+
* an exceptional condition. Stack traces are also disabled, allowing
37+
* instances of `ControlThrowable` to be safely reused.
38+
*
39+
* Instances of `ControlThrowable` should not normally have a cause.
40+
* Legacy subclasses may set a cause using `initCause`.
41+
*
42+
* @note this compat class exists so that instances of `ControlThrowable`
43+
* can be created using the same API and with the same suppression
44+
* and stack trace writability semantics across versions.
45+
*/
46+
abstract class ControlThrowable(message: String)
47+
extends Throwable(message, /*cause=*/ null, /*enableSuppression=*/ false,
48+
/*writableStackTrace=*/ false)
49+
with scala.util.control.ControlThrowable {
50+
51+
override def fillInStackTrace(): Throwable = super[Throwable].fillInStackTrace()
52+
53+
def this() = this(message = null)
54+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package scala.util.control
2+
3+
package object compat {
4+
type ControlThrowable = scala.util.control.ControlThrowable
5+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package scala.util.control.compat
2+
3+
import org.junit.Test
4+
5+
class ControlThrowableTest {
6+
@Test
7+
def doesNotSuppress(): Unit = {
8+
val t = new ControlThrowable {}
9+
t.addSuppressed(new Exception)
10+
assert(t.getSuppressed.isEmpty)
11+
}
12+
13+
@Test
14+
def doesNotHaveStackTrace(): Unit = {
15+
assert(new ControlThrowable {}.getStackTrace.isEmpty)
16+
}
17+
}

0 commit comments

Comments
 (0)