-
Notifications
You must be signed in to change notification settings - Fork 1k
/
NonLocalReturns.scala
49 lines (45 loc) · 1.52 KB
/
NonLocalReturns.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package scala.util.control
import scala.compiletime.uninitialized
/** Library implementation of nonlocal return.
*
* Usage:
*
* import scala.util.control.NonLocalReturns.*
*
* returning { ... throwReturn(x) ... }
*
* This API has been deprecated. Its functionality is better served by
*
* - `scala.util.boundary` in place of `returning`
* - `scala.util.break` in place of `throwReturn`
*
* The new abstractions work with plain `RuntimeExceptions` and are more
* performant, since returns within the scope of the same method can be
* rewritten by the compiler to jumps.
*/
@deprecated("Use scala.util.boundary instead", "3.3")
object NonLocalReturns {
@deprecated("Use scala.util.boundary.Break instead", "3.3")
class ReturnThrowable[T] extends ControlThrowable {
private var myResult: T = uninitialized
def throwReturn(result: T): Nothing = {
myResult = result
throw this
}
def result: T = myResult
}
/** Performs a nonlocal return by throwing an exception. */
@deprecated("Use scala.util.boundary.break instead", "3.3")
def throwReturn[T](result: T)(using returner: ReturnThrowable[? >: T]): Nothing =
returner.throwReturn(result)
/** Enable nonlocal returns in `op`. */
@deprecated("Use scala.util.boundary instead", "3.3")
def returning[T](op: ReturnThrowable[T] ?=> T): T = {
val returner = new ReturnThrowable[T]
try op(using returner)
catch {
case ex: ReturnThrowable[T @unchecked] =>
if (ex.eq(returner)) ex.result else throw ex
}
}
}