Repository: Kotlin/kotlinx.coroutines
File: kotlinx-coroutines-core/common/src/CoroutineStart.kt (Kotlin)

Code before:
     * execution at all, but will complete with an exception.
     */
    LAZY,

    /**
     * Atomically (i.e., in a non-cancellable way) schedules the coroutine for execution according to its context.
     * This is similar to [DEFAULT], but the coroutine cannot be cancelled before it starts executing.
     *
     * The coroutine stated with [ATOMIC] is guaranteed to start execution even if its [Job] was cancelled.
     * This [CoroutineStart] option can be used to ensure resources' disposal in case of cancellation.
     * For example, closing a channel used by a producer:
     * ```
     * fun CoroutineScope.producer(channel: SendChannel<Int>) =
     *     launch(start = CoroutineStart.ATOMIC) {
     *         try {
     *             // produce elements
     *         } finally {
     *             channel.close()
     *         }
     *     }
     * ```
     *
     * This is a **delicate** API. The coroutine starts execution even if its [Job] is canceled before starting.
     * However, the resources used in within a coroutine may rely on the cancellation mechanism,
     * and cannot be used after the [Job] cancellation. For instance, in Android development, updating a UI element
     * is not allowed if the coroutine's scope, which is tied to the element's lifecycle, has been canceled.
     *
     * Cancellability of coroutine at suspension points depends on the particular implementation details of
     * suspending functions as in [DEFAULT].
     */
    @DelicateCoroutinesApi
    ATOMIC,

    /**
     * Immediately executes the coroutine until its first suspension point _in the current thread_ similarly to
     * the coroutine being started using [Dispatchers.Unconfined]. However, when the coroutine is resumed from suspension
     * it is dispatched according to the [CoroutineDispatcher] in its context.
     *
     * This is similar to [ATOMIC] in the sense that coroutine starts executing even if it was already cancelled,
     * but the difference is that it starts executing in the same thread.
     *
     * Cancellability of coroutine at suspension points depends on the particular implementation details of
     * suspending functions as in [DEFAULT].
     *
     * ### Unconfined event loop
     *
     * Unlike [Dispatchers.Unconfined] and [MainCoroutineDispatcher.immediate], nested undispatched coroutines do not form
     * an event loop that otherwise prevents potential stack overflow in case of unlimited nesting.
     */
    UNDISPATCHED;


Review comment (suggestion):
```suggestion
     * is not allowed if the coroutine's scope, which is tied to the element's lifecycle, has been cancelled.
```
Ditto.

Code after:
     * execution at all, but will complete with an exception.
     */
    LAZY,

    /**
     * Atomically (i.e., in a non-cancellable way) schedules the coroutine for execution according to its context.
     * This is similar to [DEFAULT], but the coroutine cannot be cancelled before it starts executing.
     *
     * The coroutine started with [ATOMIC] is guaranteed to start execution even if its [Job] was cancelled.
     * This [CoroutineStart] option can be used to ensure resources' disposal in case of cancellation.
     * For example, this `producer` guarantees that the `channel` will be eventually closed,
     * even if the coroutine scope is cancelled before `producer` is called:
     * ```
     * fun CoroutineScope.producer(channel: SendChannel<Int>) =
     *     launch(start = CoroutineStart.ATOMIC) {
     *         try {
     *             // produce elements
     *         } finally {
     *             channel.close()
     *         }
     *     }
     * ```
     *
     * This is a **delicate** API. The coroutine starts execution even if its [Job] is cancelled before starting.
     * However, the resources used within a coroutine may rely on the cancellation mechanism,
     * and cannot be used after the [Job] cancellation. For instance, in Android development, updating a UI element
     * is not allowed if the coroutine's scope, which is tied to the element's lifecycle, has been cancelled.
     *
     * Cancellability of coroutine at suspension points depends on the particular implementation details of
     * suspending functions as in [DEFAULT].
     */
    @DelicateCoroutinesApi
    ATOMIC,

    /**
     * Immediately executes the coroutine until its first suspension point _in the current thread_ similarly to
     * the coroutine being started using [Dispatchers.Unconfined]. However, when the coroutine is resumed from suspension
     * it is dispatched according to the [CoroutineDispatcher] in its context.
     *
     * This is similar to [ATOMIC] in the sense that coroutine starts executing even if it was already cancelled,
     * but the difference is that it starts executing in the same thread.
     *
     * Cancellability of coroutine at suspension points depends on the particular implementation details of
     * suspending functions as in [DEFAULT].
     *
     * ### Unconfined event loop
     *
     * Unlike [Dispatchers.Unconfined] and [MainCoroutineDispatcher.immediate], nested undispatched coroutines do not form
     * an event loop that otherwise prevents potential stack overflow in case of unlimited nesting.
     */
    UNDISPATCHED;