kotlinx.coroutines icon indicating copy to clipboard operation
kotlinx.coroutines copied to clipboard

Remove InternalForInheritanceCoroutinesApi from Deferred<T>

Open Flavien opened this issue 7 months ago • 2 comments
trafficstars

What do we have now?

I want to return a CompletableDeferred<T> from a public API. I am returning it as a Deferred<T> as I don't want the consumer of the API to be able to complete the deferred, as this would mess with the internals class returning the deferred. If I just return the CompletableDeferred<T>, it can still be tempting for a consumer to upcast Deferred<T> to CompletableDeferred<T> and complete it.

So I do the following instead:

private class ReadOnlyDeferred<T>(source: Deferred<T>) : Deferred<T> by source

fun <T> execute(): Deferred<T> {
  // some code
  return ReadOnlyDeferred(result)
}

This would be a clean solution, but unfortunately I get this warning:

This class or interface requires opt-in to be implemented: This is a kotlinx. coroutines API that is not intended to be inherited from, as the library may handle predefined instances of this in a special manner. This will be an error in a future release. If you need to inherit from this, please describe your use case in https:// github. com/ Kotlin/ kotlinx. coroutines/ issues, so that we can provide a stable API for inheritance.

What should be instead?

There should be a way to achieve the above scenario without relying on internal APIs. Either provide a function allowing to return a "locked" version of the deferred:

fun <T> Deferred<T>.lock(): Deferred<T>

This is similar to CompletableFuture<T>.minimalCompletionStage().

Or remove InternalForInheritanceCoroutinesApi from Deferred<T>.

Why?

This would allow basic encapsulation for Deferred.

Flavien avatar Apr 08 '25 21:04 Flavien