Skip to content
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

Change return type of raise to Nothing #2839

Merged
merged 4 commits into from
Nov 17, 2022
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 12 additions & 12 deletions arrow-libs/core/arrow-core/api/arrow-core.api
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public inline fun <E, A> ior(semigroup: Semigroup<E>, @BuilderInference action:
public value class NullableRaise(private val cont: Raise<Nothing?>) : Raise<Nothing?> {
@EffectDSL
public fun ensure(value: Boolean): Unit = ensure(value) { null }
override fun <B> raise(r: Nothing?): B = cont.raise(r)
override fun raise(r: Nothing?): Nothing = cont.raise(r)
public fun <B> Option<B>.bind(): B = bind { raise(null) }

public fun <B> B?.bind(): B {
Expand All @@ -54,13 +54,13 @@ public value class NullableRaise(private val cont: Raise<Nothing?>) : Raise<Noth

@JvmInline
public value class ResultRaise(private val cont: Raise<Throwable>) : Raise<Throwable> {
override fun <B> raise(r: Throwable): B = cont.raise(r)
override fun raise(r: Throwable): Nothing = cont.raise(r)
public fun <B> Result<B>.bind(): B = fold(::identity) { raise(it) }
}

@JvmInline
public value class OptionRaise(private val cont: Raise<None>) : Raise<None> {
override fun <B> raise(r: None): B = cont.raise(r)
override fun raise(r: None): Nothing = cont.raise(r)
public fun <B> Option<B>.bind(): B = bind { raise(None) }
public fun ensure(value: Boolean): Unit = ensure(value) { None }

Expand All @@ -76,7 +76,7 @@ public class IorRaise<E> @PublishedApi internal constructor(semigroup: Semigroup
// TODO this is a mess...
@PublishedApi
internal var leftState: AtomicRef<Any?> = AtomicRef(EmptyValue)
override fun <B> raise(r: E): B = effect.raise(combine(r))
override fun raise(r: E): Nothing = effect.raise(combine(r))

public fun <B> Ior<E, B>.bind(): B =
when (this) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,7 @@ import kotlin.jvm.JvmMultifileClass
* val error = "Error"
* val exit = CompletableDeferred<ExitCase>()
* effect<String, Int> {
* parZip({ awaitExitCase<Int>(exit) }, { raise<Int>(error) }) { a, b -> a + b }
* parZip({ awaitExitCase<Int>(exit) }, { raise(error) }) { a: Int, b: Int -> a + b }
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The explicit lambda signature is needed here because otherwise the type of b is unconstrained and the + operator function can't be resolved.

* }.fold({ it shouldBe error }, { fail("Int can never be the result") })
* exit.await().shouldBeTypeOf<ExitCase>()
* }
Expand Down Expand Up @@ -425,7 +425,7 @@ import kotlin.jvm.JvmMultifileClass
* val error = "Error"
* val exit = CompletableDeferred<ExitCase>()
* effect<String, Int> {
* raceN({ awaitExitCase<Int>(exit) }) { raise<Int>(error) }
* raceN({ awaitExitCase<Int>(exit) }) { raise(error) }
* .merge() // Flatten Either<Int, Int> 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
Expand Down Expand Up @@ -497,7 +497,7 @@ import kotlin.jvm.JvmMultifileClass
* resourceScope {
* effect<String, Int> {
* val reader = bufferedReader("build.gradle.kts")
* raise<Int>(error)
* raise(error)
* reader.lineSequence().count()
* }.fold({ it shouldBe error }, { fail("Int can never be the result") })
* }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ internal fun <R> 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<Any?> {
override fun <B> 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. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public annotation class EffectDSL
public interface Raise<in R> {

/** Raise a _logical failure_ of type [R] */
public fun <A> raise(r: R): A
public fun raise(r: R): Nothing

/**
* Invoke an [EagerEffect] inside `this` [Raise] context.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class EagerEffectSpec : StringSpec({
val promise = CompletableDeferred<Int>()
eagerEffect {
try {
raise<Int>(s)
raise(s)
} finally {
require(promise.complete(i))
}
Expand Down Expand Up @@ -141,31 +141,34 @@ class EagerEffectSpec : StringSpec({
}
}

@Suppress("UNREACHABLE_CODE")
"catch - error path and recover" {
checkAll(Arb.int(), Arb.string()) { int, fallback ->
eagerEffect<Int, String> {
raise<String>(int)
raise(int)
fail("It should never reach this point")
}.recover<Int, Nothing, String> { fallback }
.runCont() shouldBe fallback
}
}

@Suppress("UNREACHABLE_CODE")
"catch - error path and re-raise" {
checkAll(Arb.int(), Arb.string()) { int, fallback ->
eagerEffect<Int, Unit> {
raise<String>(int)
raise(int)
fail("It should never reach this point")
}.recover { raise(fallback) }
.runCont() shouldBe fallback
}
}

@Suppress("UNREACHABLE_CODE")
"catch - error path and throw" {
checkAll(Arb.int(), Arb.string()) { int, msg ->
shouldThrow<RuntimeException> {
eagerEffect<Int, String> {
raise<String>(int)
raise(int)
fail("It should never reach this point")
}.recover<Int, Nothing, String> { throw RuntimeException(msg) }
.runCont()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ class EffectSpec :
val promise = CompletableDeferred<Int>()
effect {
try {
raise<Int>(s().suspend())
raise(s().suspend())
} finally {
require(promise.complete(i()))
}
Expand Down Expand Up @@ -132,7 +132,7 @@ class EffectSpec :
"short-circuit" {
checkAll(Arb.string().suspend()) { msg ->
effect {
raise<Int>(msg())
raise(msg())
}.runCont() shouldBe msg()
}
}
Expand Down Expand Up @@ -299,31 +299,34 @@ class EffectSpec :
}
}

@Suppress("UNREACHABLE_CODE")
"catch - error path and recover" {
checkAll(Arb.int().suspend(), Arb.string().suspend()) { int, fallback ->
effect<Int, String> {
raise<String>(int())
raise(int())
fail("It should never reach this point")
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line now warns about unreachable code. Same in the other similar tests. Is this line still useful, or should it be removed?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that test is still useful. It verifies that passed raise no code will be executed, which is also confirmed by the IDEA inspection now 🥳

So, I think we should suppress this warning if possible. (Not sure what @Supress is needed for this).

}.recover<Int, Nothing, String> { fallback() }
.runCont() shouldBe fallback()
}
}

@Suppress("UNREACHABLE_CODE")
"catch - error path and re-raise" {
checkAll(Arb.int().suspend(), Arb.string().suspend()) { int, fallback ->
effect<Int, Unit> {
raise<String>(int())
raise(int())
fail("It should never reach this point")
}.recover { raise(fallback()) }
.runCont() shouldBe fallback()
}
}

@Suppress("UNREACHABLE_CODE")
"catch - error path and throw" {
checkAll(Arb.int().suspend(), Arb.string().suspend()) { int, msg ->
shouldThrow<RuntimeException> {
effect<Int, String> {
raise<String>(int())
raise(int())
fail("It should never reach this point")
}.recover<Int, Nothing, String> { throw RuntimeException(msg()) }
.runCont()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ suspend fun <A> awaitExitCase(exit: CompletableDeferred<ExitCase>): A =
val error = "Error"
val exit = CompletableDeferred<ExitCase>()
effect<String, Int> {
parZip({ awaitExitCase<Int>(exit) }, { raise<Int>(error) }) { a, b -> a + b }
parZip({ awaitExitCase<Int>(exit) }, { raise(error) }) { a: Int, b: Int -> a + b }
}.fold({ it shouldBe error }, { fail("Int can never be the result") })
exit.await().shouldBeTypeOf<ExitCase>()
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ suspend fun main() {
val error = "Error"
val exit = CompletableDeferred<ExitCase>()
effect<String, Int> {
raceN({ awaitExitCase<Int>(exit) }) { raise<Int>(error) }
raceN({ awaitExitCase<Int>(exit) }) { raise(error) }
.merge() // Flatten Either<Int, Int> 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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ suspend fun main() {
resourceScope {
effect<String, Int> {
val reader = bufferedReader("build.gradle.kts")
raise<Int>(error)
raise(error)
reader.lineSequence().count()
}.fold({ it shouldBe error }, { fail("Int can never be the result") })
}
Expand Down