Skip to content

Commit a9f8c0d

Browse files
committed
Make Flow.fold inlineable
* It is not that useful in an application code (-> is extracted into method), so won't bloat bytecode too much * It is crucial enough as building block to avoid excess allocations * Additionally mark inlined builders with labeled return to workaround KT-28938
1 parent 2596414 commit a9f8c0d

File tree

3 files changed

+11
-10
lines changed

3 files changed

+11
-10
lines changed

kotlinx-coroutines-core/common/src/flow/operators/Context.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public fun <T> Flow<T>.flowOn(flowContext: CoroutineContext, bufferSize: Int = 1
5050
coroutineScope {
5151
val channel = produce(flowContext, capacity = bufferSize) {
5252
collect { value ->
53-
send(value)
53+
return@collect send(value)
5454
}
5555
}
5656
channel.consumeEach { value ->
@@ -98,7 +98,7 @@ public fun <T, R> Flow<T>.flowWith(
9898
val originalContext = coroutineContext.minusKey(Job)
9999
val prepared = source.flowOn(originalContext, bufferSize)
100100
builder(prepared).flowOn(flowContext, bufferSize).collect { value ->
101-
emit(value)
101+
return@collect emit(value)
102102
}
103103
}
104104
}

kotlinx-coroutines-core/common/src/flow/operators/Transform.kt

+7-6
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ import kotlinx.coroutines.flow.unsafeFlow as flow
2929
public inline fun <T, R> Flow<T>.transform(@BuilderInference crossinline transform: suspend FlowCollector<R>.(value: T) -> Unit): Flow<R> {
3030
return flow {
3131
collect { value ->
32-
transform(value)
32+
// kludge, without it Unit will be returned and TCE won't kick in, KT-28938
33+
return@collect transform(value)
3334
}
3435
}
3536
}
@@ -40,7 +41,7 @@ public inline fun <T, R> Flow<T>.transform(@BuilderInference crossinline transfo
4041
@FlowPreview
4142
public inline fun <T> Flow<T>.filter(crossinline predicate: suspend (T) -> Boolean): Flow<T> = flow {
4243
collect { value ->
43-
if (predicate(value)) emit(value)
44+
if (predicate(value)) return@collect emit(value)
4445
}
4546
}
4647

@@ -50,7 +51,7 @@ public inline fun <T> Flow<T>.filter(crossinline predicate: suspend (T) -> Boole
5051
@FlowPreview
5152
public inline fun <T> Flow<T>.filterNot(crossinline predicate: suspend (T) -> Boolean): Flow<T> = flow {
5253
collect { value ->
53-
if (!predicate(value)) emit(value)
54+
if (!predicate(value)) return@collect emit(value)
5455
}
5556
}
5657

@@ -66,15 +67,15 @@ public inline fun <reified R> Flow<*>.filterIsInstance(): Flow<R> = filter { it
6667
*/
6768
@FlowPreview
6869
public fun <T: Any> Flow<T?>.filterNotNull(): Flow<T> = flow<T> {
69-
collect { value -> if (value != null) emit(value) }
70+
collect { value -> if (value != null) return@collect emit(value) }
7071
}
7172

7273
/**
7374
* Returns a flow containing the results of applying the given [transform] function to each value of the original flow.
7475
*/
7576
@FlowPreview
7677
public inline fun <T, R> Flow<T>.map(crossinline transform: suspend (value: T) -> R): Flow<R> = transform { value ->
77-
emit(transform(value))
78+
return@transform emit(transform(value))
7879
}
7980

8081
/**
@@ -83,7 +84,7 @@ public inline fun <T, R> Flow<T>.map(crossinline transform: suspend (value: T) -
8384
@FlowPreview
8485
public inline fun <T, R: Any> Flow<T>.mapNotNull(crossinline transform: suspend (value: T) -> R?): Flow<R> = transform { value ->
8586
val transformed = transform(value) ?: return@transform
86-
emit(transformed)
87+
return@transform emit(transformed)
8788
}
8889

8990
/**

kotlinx-coroutines-core/common/src/flow/terminal/Reduce.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,9 @@ public suspend fun <S, T : S> Flow<T>.reduce(operation: suspend (accumulator: S,
3838
* Accumulates value starting with [initial] value and applying [operation] current accumulator value and each element
3939
*/
4040
@FlowPreview
41-
public suspend fun <T, R> Flow<T>.fold(
41+
public suspend inline fun <T, R> Flow<T>.fold(
4242
initial: R,
43-
operation: suspend (acc: R, value: T) -> R
43+
crossinline operation: suspend (acc: R, value: T) -> R
4444
): R {
4545
var accumulator = initial
4646
collect { value ->

0 commit comments

Comments
 (0)