Skip to content

Remove InternalForInheritanceCoroutinesApi from Deferred<T> #4408

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

Open
Flavien opened this issue Apr 8, 2025 · 2 comments
Open

Remove InternalForInheritanceCoroutinesApi from Deferred<T> #4408

Flavien opened this issue Apr 8, 2025 · 2 comments

Comments

@Flavien
Copy link

Flavien commented Apr 8, 2025

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.

@dkhalanskyjb
Copy link
Collaborator

Thanks! The use case is clear, and we already have things like https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/as-state-flow.html, so adding this is straightforward: #4410

@Flavien
Copy link
Author

Flavien commented Apr 9, 2025

Wow, that was fast, thanks @dkhalanskyjb .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants