Skip to content

CompletableDeferred builder with nullable generic parameter can be misused #4428

@vsalavatov

Description

@vsalavatov

Consider a code like this:

interface T

object BadT : T
class GoodT : T

fun CoroutineScope.doStuff(flag: Boolean): Deferred<T> {
  if (!flag) return CompletableDeferred(BadT)
  return async { computeGoodT() }
}

after some thinking I decided to drop BadT and use nullability instead, so I naturally changed the code to

interface T

class GoodT : T

fun CoroutineScope.doStuff(flag: Boolean): Deferred<T?> {
  if (!flag) return CompletableDeferred(null)
  return async { computeGoodT() }
}

And was puzzled to see my tests stuck. During an investigation I noticed that after my change the CompletableDeferred started to resolve to public fun <T> CompletableDeferred(parent: Job? = null) instead of public fun <T> CompletableDeferred(value: T). I believe this misuse might occasionally happen, so an inspection would be nice

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions