From 33bfa6ba878d98d3e8aa20f0f4dce74c20019e73 Mon Sep 17 00:00:00 2001 From: Sam Cooper Date: Mon, 10 Oct 2022 11:17:44 +0100 Subject: [PATCH 1/3] Change return type of raise to Nothing Implements #2805 --- .../kotlin/arrow/core/continuations/Builders.kt | 8 ++++---- .../kotlin/arrow/core/continuations/Effect.kt | 6 +++--- .../commonMain/kotlin/arrow/core/continuations/Fold.kt | 2 +- .../kotlin/arrow/core/continuations/Raise.kt | 2 +- .../kotlin/arrow/core/continuations/EagerEffectSpec.kt | 8 ++++---- .../kotlin/arrow/core/continuations/EffectSpec.kt | 10 +++++----- .../src/jvmTest/kotlin/examples/example-effect-05.kt | 2 +- .../src/jvmTest/kotlin/examples/example-effect-07.kt | 2 +- .../src/jvmTest/kotlin/examples/example-effect-09.kt | 2 +- 9 files changed, 21 insertions(+), 21 deletions(-) diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/Builders.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/Builders.kt index 46b8e8ea3b8..3225fda9fee 100644 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/Builders.kt +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/Builders.kt @@ -38,7 +38,7 @@ public inline fun ior(semigroup: Semigroup, @BuilderInference action: public value class NullableRaise(private val cont: Raise) : Raise { @EffectDSL public fun ensure(value: Boolean): Unit = ensure(value) { null } - override fun raise(r: Nothing?): B = cont.raise(r) + override fun raise(r: Nothing?): Nothing = cont.raise(r) public fun Option.bind(): B = bind { raise(null) } public fun B?.bind(): B { @@ -54,13 +54,13 @@ public value class NullableRaise(private val cont: Raise) : Raise) : Raise { - override fun raise(r: Throwable): B = cont.raise(r) + override fun raise(r: Throwable): Nothing = cont.raise(r) public fun Result.bind(): B = fold(::identity) { raise(it) } } @JvmInline public value class OptionRaise(private val cont: Raise) : Raise { - override fun raise(r: None): B = cont.raise(r) + override fun raise(r: None): Nothing = cont.raise(r) public fun Option.bind(): B = bind { raise(None) } public fun ensure(value: Boolean): Unit = ensure(value) { None } @@ -76,7 +76,7 @@ public class IorRaise @PublishedApi internal constructor(semigroup: Semigroup // TODO this is a mess... @PublishedApi internal var leftState: AtomicRef = AtomicRef(EmptyValue) - override fun raise(r: E): B = effect.raise(combine(r)) + override fun raise(r: E): Nothing = effect.raise(combine(r)) public fun Ior.bind(): B = when (this) { diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/Effect.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/Effect.kt index dc083ce81ad..0c694f49243 100644 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/Effect.kt +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/Effect.kt @@ -355,7 +355,7 @@ import kotlin.jvm.JvmMultifileClass * val error = "Error" * val exit = CompletableDeferred() * effect { - * parZip({ awaitExitCase(exit) }, { raise(error) }) { a, b -> a + b } + * parZip({ awaitExitCase(exit) }, { raise(error) }) { a: Int, b: Int -> a + b } * }.fold({ it shouldBe error }, { fail("Int can never be the result") }) * exit.await().shouldBeTypeOf() * } @@ -425,7 +425,7 @@ import kotlin.jvm.JvmMultifileClass * val error = "Error" * val exit = CompletableDeferred() * effect { - * raceN({ awaitExitCase(exit) }) { raise(error) } + * raceN({ awaitExitCase(exit) }) { raise(error) } * .merge() // Flatten Either result from race into Int * }.fold({ msg -> msg shouldBe error }, { fail("Int can never be the result") }) * // It's possible not all parallel task got launched, and in those cases awaitCancellation never ran @@ -497,7 +497,7 @@ import kotlin.jvm.JvmMultifileClass * resourceScope { * effect { * val reader = bufferedReader("build.gradle.kts") - * raise(error) + * raise(error) * reader.lineSequence().count() * }.fold({ it shouldBe error }, { fail("Int can never be the result") }) * } diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/Fold.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/Fold.kt index 495e14de5fb..b43d339ef92 100644 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/Fold.kt +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/Fold.kt @@ -72,7 +72,7 @@ internal fun CancellationException.raisedOrRethrow(raise: DefaultRaise): R = /** Serves as both purposes of a scope-reference token, and a default implementation for Raise. */ @PublishedApi internal class DefaultRaise : Raise { - override fun raise(r: Any?): B = throw RaiseCancellationException(r, this) + override fun raise(r: Any?): Nothing = throw RaiseCancellationException(r, this) } /** CancellationException is required to cancel coroutines when shifting from within them. */ diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/Raise.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/Raise.kt index 268951b24d3..8a85ca1a769 100644 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/Raise.kt +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/Raise.kt @@ -61,7 +61,7 @@ public annotation class EffectDSL public interface Raise { /** Raise a _logical failure_ of type [R] */ - public fun raise(r: R): A + public fun raise(r: R): Nothing /** * Invoke an [EagerEffect] inside `this` [Raise] context. diff --git a/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/continuations/EagerEffectSpec.kt b/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/continuations/EagerEffectSpec.kt index 671306bb6ac..3d566951f71 100644 --- a/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/continuations/EagerEffectSpec.kt +++ b/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/continuations/EagerEffectSpec.kt @@ -36,7 +36,7 @@ class EagerEffectSpec : StringSpec({ val promise = CompletableDeferred() eagerEffect { try { - raise(s) + raise(s) } finally { require(promise.complete(i)) } @@ -144,7 +144,7 @@ class EagerEffectSpec : StringSpec({ "catch - error path and recover" { checkAll(Arb.int(), Arb.string()) { int, fallback -> eagerEffect { - raise(int) + raise(int) fail("It should never reach this point") }.recover { fallback } .runCont() shouldBe fallback @@ -154,7 +154,7 @@ class EagerEffectSpec : StringSpec({ "catch - error path and re-raise" { checkAll(Arb.int(), Arb.string()) { int, fallback -> eagerEffect { - raise(int) + raise(int) fail("It should never reach this point") }.recover { raise(fallback) } .runCont() shouldBe fallback @@ -165,7 +165,7 @@ class EagerEffectSpec : StringSpec({ checkAll(Arb.int(), Arb.string()) { int, msg -> shouldThrow { eagerEffect { - raise(int) + raise(int) fail("It should never reach this point") }.recover { throw RuntimeException(msg) } .runCont() diff --git a/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/continuations/EffectSpec.kt b/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/continuations/EffectSpec.kt index 569651f962e..2da911e0661 100644 --- a/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/continuations/EffectSpec.kt +++ b/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/continuations/EffectSpec.kt @@ -47,7 +47,7 @@ class EffectSpec : val promise = CompletableDeferred() effect { try { - raise(s().suspend()) + raise(s().suspend()) } finally { require(promise.complete(i())) } @@ -132,7 +132,7 @@ class EffectSpec : "short-circuit" { checkAll(Arb.string().suspend()) { msg -> effect { - raise(msg()) + raise(msg()) }.runCont() shouldBe msg() } } @@ -302,7 +302,7 @@ class EffectSpec : "catch - error path and recover" { checkAll(Arb.int().suspend(), Arb.string().suspend()) { int, fallback -> effect { - raise(int()) + raise(int()) fail("It should never reach this point") }.recover { fallback() } .runCont() shouldBe fallback() @@ -312,7 +312,7 @@ class EffectSpec : "catch - error path and re-raise" { checkAll(Arb.int().suspend(), Arb.string().suspend()) { int, fallback -> effect { - raise(int()) + raise(int()) fail("It should never reach this point") }.recover { raise(fallback()) } .runCont() shouldBe fallback() @@ -323,7 +323,7 @@ class EffectSpec : checkAll(Arb.int().suspend(), Arb.string().suspend()) { int, msg -> shouldThrow { effect { - raise(int()) + raise(int()) fail("It should never reach this point") }.recover { throw RuntimeException(msg()) } .runCont() diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-effect-05.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-effect-05.kt index c17af634fe8..09cd2ef8212 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-effect-05.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-effect-05.kt @@ -19,7 +19,7 @@ suspend fun awaitExitCase(exit: CompletableDeferred): A = val error = "Error" val exit = CompletableDeferred() effect { - parZip({ awaitExitCase(exit) }, { raise(error) }) { a, b -> a + b } + parZip({ awaitExitCase(exit) }, { raise(error) }) { a: Int, b: Int -> a + b } }.fold({ it shouldBe error }, { fail("Int can never be the result") }) exit.await().shouldBeTypeOf() } diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-effect-07.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-effect-07.kt index 33f4a45af98..8d9295d3545 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-effect-07.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-effect-07.kt @@ -23,7 +23,7 @@ suspend fun main() { val error = "Error" val exit = CompletableDeferred() effect { - raceN({ awaitExitCase(exit) }) { raise(error) } + raceN({ awaitExitCase(exit) }) { raise(error) } .merge() // Flatten Either result from race into Int }.fold({ msg -> msg shouldBe error }, { fail("Int can never be the result") }) // It's possible not all parallel task got launched, and in those cases awaitCancellation never ran diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-effect-09.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-effect-09.kt index e3426a5911b..97083577588 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-effect-09.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/examples/example-effect-09.kt @@ -26,7 +26,7 @@ suspend fun main() { resourceScope { effect { val reader = bufferedReader("build.gradle.kts") - raise(error) + raise(error) reader.lineSequence().count() }.fold({ it shouldBe error }, { fail("Int can never be the result") }) } From 77e308e5b97ad7b909921d97e46667dd1a3958fb Mon Sep 17 00:00:00 2001 From: Sam Cooper Date: Mon, 10 Oct 2022 12:34:59 +0100 Subject: [PATCH 2/3] Update public api with ./gradlew apiDump --- arrow-libs/core/arrow-core/api/arrow-core.api | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/arrow-libs/core/arrow-core/api/arrow-core.api b/arrow-libs/core/arrow-core/api/arrow-core.api index 04c5171a396..c7dc7cb7f89 100644 --- a/arrow-libs/core/arrow-core/api/arrow-core.api +++ b/arrow-libs/core/arrow-core/api/arrow-core.api @@ -2597,7 +2597,7 @@ public final class arrow/core/continuations/DefaultRaise : arrow/core/continuati public fun catch (Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function3;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun invoke (Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; public fun invoke (Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; - public fun raise (Ljava/lang/Object;)Ljava/lang/Object; + public fun raise (Ljava/lang/Object;)Ljava/lang/Void; public fun recover (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object; public fun recover (Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function3;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun recover (Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function3;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; @@ -2665,7 +2665,7 @@ public final class arrow/core/continuations/IorRaise : arrow/core/continuations/ public fun invoke (Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun maybeCombine (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; public fun plus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun raise (Ljava/lang/Object;)Ljava/lang/Object; + public fun raise (Ljava/lang/Object;)Ljava/lang/Void; public fun recover (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object; public fun recover (Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function3;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun recover (Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function3;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; @@ -2704,9 +2704,9 @@ public final class arrow/core/continuations/NullableRaise : arrow/core/continuat public fun invoke (Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static fun invoke-impl (Larrow/core/continuations/Raise;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; public static fun invoke-impl (Larrow/core/continuations/Raise;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; - public synthetic fun raise (Ljava/lang/Object;)Ljava/lang/Object; - public fun raise (Ljava/lang/Void;)Ljava/lang/Object; - public static fun raise-impl (Larrow/core/continuations/Raise;Ljava/lang/Void;)Ljava/lang/Object; + public synthetic fun raise (Ljava/lang/Object;)Ljava/lang/Void; + public fun raise (Ljava/lang/Void;)Ljava/lang/Void; + public static fun raise-impl (Larrow/core/continuations/Raise;Ljava/lang/Void;)Ljava/lang/Void; public fun recover (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object; public fun recover (Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function3;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun recover (Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function3;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; @@ -2749,9 +2749,9 @@ public final class arrow/core/continuations/OptionRaise : arrow/core/continuatio public fun invoke (Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static fun invoke-impl (Larrow/core/continuations/Raise;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; public static fun invoke-impl (Larrow/core/continuations/Raise;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; - public fun raise (Larrow/core/None;)Ljava/lang/Object; - public synthetic fun raise (Ljava/lang/Object;)Ljava/lang/Object; - public static fun raise-impl (Larrow/core/continuations/Raise;Larrow/core/None;)Ljava/lang/Object; + public fun raise (Larrow/core/None;)Ljava/lang/Void; + public synthetic fun raise (Ljava/lang/Object;)Ljava/lang/Void; + public static fun raise-impl (Larrow/core/continuations/Raise;Larrow/core/None;)Ljava/lang/Void; public fun recover (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object; public fun recover (Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function3;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun recover (Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function3;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; @@ -2774,7 +2774,7 @@ public abstract interface class arrow/core/continuations/Raise { public abstract fun catch (Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function3;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public abstract fun invoke (Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; public abstract fun invoke (Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; - public abstract fun raise (Ljava/lang/Object;)Ljava/lang/Object; + public abstract fun raise (Ljava/lang/Object;)Ljava/lang/Void; public abstract fun recover (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object; public abstract fun recover (Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function3;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public abstract fun recover (Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function3;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; @@ -2833,9 +2833,9 @@ public final class arrow/core/continuations/ResultRaise : arrow/core/continuatio public fun invoke (Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public static fun invoke-impl (Larrow/core/continuations/Raise;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; public static fun invoke-impl (Larrow/core/continuations/Raise;Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; - public synthetic fun raise (Ljava/lang/Object;)Ljava/lang/Object; - public fun raise (Ljava/lang/Throwable;)Ljava/lang/Object; - public static fun raise-impl (Larrow/core/continuations/Raise;Ljava/lang/Throwable;)Ljava/lang/Object; + public synthetic fun raise (Ljava/lang/Object;)Ljava/lang/Void; + public fun raise (Ljava/lang/Throwable;)Ljava/lang/Void; + public static fun raise-impl (Larrow/core/continuations/Raise;Ljava/lang/Throwable;)Ljava/lang/Void; public fun recover (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object; public fun recover (Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function3;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun recover (Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function3;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; From 6dd6eaccfd9d948f21ac0a01f79ccf58bd631060 Mon Sep 17 00:00:00 2001 From: Sam Cooper Date: Mon, 10 Oct 2022 12:44:48 +0100 Subject: [PATCH 3/3] Suppress warnings for unreachable calls to fail in tests The test is verifying that no code will be executed after a call to raise, so it's actually testing the very behaviour that the compiler is warning us about. --- .../kotlin/arrow/core/continuations/EagerEffectSpec.kt | 3 +++ .../commonTest/kotlin/arrow/core/continuations/EffectSpec.kt | 3 +++ 2 files changed, 6 insertions(+) diff --git a/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/continuations/EagerEffectSpec.kt b/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/continuations/EagerEffectSpec.kt index 3d566951f71..8286e614132 100644 --- a/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/continuations/EagerEffectSpec.kt +++ b/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/continuations/EagerEffectSpec.kt @@ -141,6 +141,7 @@ class EagerEffectSpec : StringSpec({ } } + @Suppress("UNREACHABLE_CODE") "catch - error path and recover" { checkAll(Arb.int(), Arb.string()) { int, fallback -> eagerEffect { @@ -151,6 +152,7 @@ class EagerEffectSpec : StringSpec({ } } + @Suppress("UNREACHABLE_CODE") "catch - error path and re-raise" { checkAll(Arb.int(), Arb.string()) { int, fallback -> eagerEffect { @@ -161,6 +163,7 @@ class EagerEffectSpec : StringSpec({ } } + @Suppress("UNREACHABLE_CODE") "catch - error path and throw" { checkAll(Arb.int(), Arb.string()) { int, msg -> shouldThrow { diff --git a/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/continuations/EffectSpec.kt b/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/continuations/EffectSpec.kt index 2da911e0661..eb4b91b8c5c 100644 --- a/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/continuations/EffectSpec.kt +++ b/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/continuations/EffectSpec.kt @@ -299,6 +299,7 @@ class EffectSpec : } } + @Suppress("UNREACHABLE_CODE") "catch - error path and recover" { checkAll(Arb.int().suspend(), Arb.string().suspend()) { int, fallback -> effect { @@ -309,6 +310,7 @@ class EffectSpec : } } + @Suppress("UNREACHABLE_CODE") "catch - error path and re-raise" { checkAll(Arb.int().suspend(), Arb.string().suspend()) { int, fallback -> effect { @@ -319,6 +321,7 @@ class EffectSpec : } } + @Suppress("UNREACHABLE_CODE") "catch - error path and throw" { checkAll(Arb.int().suspend(), Arb.string().suspend()) { int, msg -> shouldThrow {