Skip to content

Commit 83943ef

Browse files
committed
Get rid of deprecated FlowCollector<*>.withContext
This migration was motivated by the limited invariant preservation check, which is now more advanced; Additionally, such migration prohibits meaningful use-cases like "compute value in encapsulated context and then emit in flow context" Fixes #1616
1 parent 340d501 commit 83943ef

File tree

4 files changed

+11
-27
lines changed

4 files changed

+11
-27
lines changed

binary-compatibility-validator/reference-public-api/kotlinx-coroutines-core.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -969,7 +969,6 @@ public final class kotlinx/coroutines/flow/FlowKt {
969969
public static final fun transform (Lkotlinx/coroutines/flow/Flow;Lkotlin/jvm/functions/Function3;)Lkotlinx/coroutines/flow/Flow;
970970
public static final fun transformLatest (Lkotlinx/coroutines/flow/Flow;Lkotlin/jvm/functions/Function3;)Lkotlinx/coroutines/flow/Flow;
971971
public static final fun unsafeTransform (Lkotlinx/coroutines/flow/Flow;Lkotlin/jvm/functions/Function3;)Lkotlinx/coroutines/flow/Flow;
972-
public static final fun withContext (Lkotlinx/coroutines/flow/FlowCollector;Lkotlin/coroutines/CoroutineContext;Lkotlin/jvm/functions/Function1;)V
973972
public static final fun withIndex (Lkotlinx/coroutines/flow/Flow;)Lkotlinx/coroutines/flow/Flow;
974973
public static final fun zip (Lkotlinx/coroutines/flow/Flow;Lkotlinx/coroutines/flow/Flow;Lkotlin/jvm/functions/Function3;)Lkotlinx/coroutines/flow/Flow;
975974
}

docs/flow.md

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -708,17 +708,15 @@ fun main() = runBlocking<Unit> {
708708
709709
This code produces the following exception:
710710

711-
<!--- TEST EXCEPTION
711+
```text
712712
Exception in thread "main" java.lang.IllegalStateException: Flow invariant is violated:
713713
Flow was collected in [CoroutineId(1), "coroutine#1":BlockingCoroutine{Active}@5511c7f8, BlockingEventLoop@2eac3323],
714714
but emission happened in [CoroutineId(1), "coroutine#1":DispatchedCoroutine{Active}@2dae0000, DefaultDispatcher].
715715
Please refer to 'flow' documentation or use 'flowOn' instead
716716
at ...
717-
-->
718-
719-
> Note that we had to use a fully qualified name of the [kotlinx.coroutines.withContext][withContext] function in this example to
720-
demonstrate this exception. A short name of `withContext` would have resolved to a special stub function that
721-
produces a compilation error to prevent us from running into this problem.
717+
```
718+
719+
<!--- TEST EXCEPTION -->
722720

723721
#### flowOn operator
724722

kotlinx-coroutines-core/common/src/flow/Migration.kt

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -126,14 +126,6 @@ public fun <T> Flow<T>.onErrorResume(fallback: Flow<T>): Flow<T> = noImpl()
126126
)
127127
public fun <T> Flow<T>.onErrorResumeNext(fallback: Flow<T>): Flow<T> = noImpl()
128128

129-
/**
130-
* Self-explanatory, the reason of deprecation is "context preservation" property (you can read more in [Flow] documentation)
131-
* @suppress
132-
**/
133-
@Suppress("UNUSED_PARAMETER", "UNUSED", "DeprecatedCallableAddReplaceWith")
134-
@Deprecated(message = "withContext in flow body is deprecated, use flowOn instead", level = DeprecationLevel.ERROR)
135-
public fun <T, R> FlowCollector<T>.withContext(context: CoroutineContext, block: suspend () -> R): Unit = noImpl()
136-
137129
/**
138130
* `subscribe` is Rx-specific API that has no direct match in flows.
139131
* One can use [launchIn] instead, for example the following:

kotlinx-coroutines-core/common/test/flow/FlowInvariantsTest.kt

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -40,39 +40,37 @@ class FlowInvariantsTest : TestBase() {
4040
@Test
4141
fun testWithContextContract() = runParametrizedTest<Int>(IllegalStateException::class) { flow ->
4242
flow {
43-
kotlinx.coroutines.withContext(NonCancellable) {
43+
withContext(NonCancellable) {
4444
emit(1)
4545
}
4646
}.collect {
47-
assertEquals(1, it)
47+
expectUnreached()
4848
}
4949
}
5050

5151
@Test
5252
fun testWithDispatcherContractViolated() = runParametrizedTest<Int>(IllegalStateException::class) { flow ->
5353
flow {
54-
kotlinx.coroutines.withContext(NamedDispatchers("foo")) {
54+
withContext(NamedDispatchers("foo")) {
5555
emit(1)
5656
}
5757
}.collect {
58-
fail()
58+
expectUnreached()
5959
}
6060
}
6161

6262
@Test
6363
fun testCachedInvariantCheckResult() = runParametrizedTest<Int> { flow ->
6464
flow {
6565
emit(1)
66-
6766
try {
68-
kotlinx.coroutines.withContext(NamedDispatchers("foo")) {
67+
withContext(NamedDispatchers("foo")) {
6968
emit(1)
7069
}
7170
fail()
7271
} catch (e: IllegalStateException) {
7372
expect(2)
7473
}
75-
7674
emit(3)
7775
}.collect {
7876
expect(it)
@@ -83,11 +81,11 @@ class FlowInvariantsTest : TestBase() {
8381
@Test
8482
fun testWithNameContractViolated() = runParametrizedTest<Int>(IllegalStateException::class) { flow ->
8583
flow {
86-
kotlinx.coroutines.withContext(CoroutineName("foo")) {
84+
withContext(CoroutineName("foo")) {
8785
emit(1)
8886
}
8987
}.collect {
90-
fail()
88+
expectUnreached()
9189
}
9290
}
9391

@@ -107,7 +105,6 @@ class FlowInvariantsTest : TestBase() {
107105
}
108106
}.join()
109107
}
110-
111108
assertEquals("original", result)
112109
}
113110

@@ -116,7 +113,6 @@ class FlowInvariantsTest : TestBase() {
116113
flow { emit(1) }.buffer(EmptyCoroutineContext, flow).collect {
117114
expect(1)
118115
}
119-
120116
finish(2)
121117
}
122118

@@ -125,7 +121,6 @@ class FlowInvariantsTest : TestBase() {
125121
flow { emit(1) }.buffer(Dispatchers.Unconfined, flow).collect {
126122
expect(1)
127123
}
128-
129124
finish(2)
130125
}
131126

0 commit comments

Comments
 (0)