FIR: revert a hack that allows overriding T!! with T
1. this should've been only done if the language feature for validating
that is disabled;
2. that feature probably won't matter by the time FIR is stable;
3. it only worked because type enhancement of type arguments is broken
anyway - a more correct hack would be to provide a custom
ConeTypePreparator.
This commit is contained in:
@@ -20,7 +20,7 @@ FILE: main.kt
|
||||
|
||||
}
|
||||
public final fun test_1(b: R|B<kotlin/Int>|, x: R|kotlin/Int|, inv: R|Inv<kotlin/Int>|): R|kotlin/Unit| {
|
||||
R|<local>/b|.R|SubstitutionOverride</B.take: R|kotlin/String|>|(R|<local>/x|)
|
||||
R|<local>/b|.<Inapplicable(INAPPLICABLE): /B.take>#(Null(null))
|
||||
R|<local>/b|.<Ambiguity: take, [/B.take, /B.take]>#(R|<local>/x|)
|
||||
R|<local>/b|.<Ambiguity: take, [/B.take, /B.take]>#(Null(null))
|
||||
R|<local>/b|.R|SubstitutionOverride</B.takeInv: R|kotlin/String|>|(R|<local>/inv|)
|
||||
}
|
||||
|
||||
+4
-4
@@ -16,8 +16,8 @@ public abstract class A<T, V> {
|
||||
|
||||
class Inv<T>
|
||||
|
||||
open class B<V> : A<Any, V>() {
|
||||
override fun take(value: V): String {
|
||||
open <!ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED!>class B<!><V> : A<Any, V>() {
|
||||
<!NOTHING_TO_OVERRIDE!>override<!> fun take(value: V): String {
|
||||
return ""
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ open class B<V> : A<Any, V>() {
|
||||
}
|
||||
|
||||
fun test_1(b: B<Int>, x: Int, inv: Inv<Int>) {
|
||||
b.take(x)
|
||||
b.take(<!NULL_FOR_NONNULL_TYPE!>null<!>)
|
||||
b.<!OVERLOAD_RESOLUTION_AMBIGUITY!>take<!>(x)
|
||||
b.<!NONE_APPLICABLE!>take<!>(null)
|
||||
b.takeInv(inv)
|
||||
}
|
||||
|
||||
+3
-8
@@ -19,7 +19,7 @@ import org.jetbrains.kotlin.types.model.KotlinTypeMarker
|
||||
import org.jetbrains.kotlin.types.model.SimpleTypeMarker
|
||||
|
||||
class FirStandardOverrideChecker(private val session: FirSession) : FirAbstractOverrideChecker() {
|
||||
private val context: ConeTypeContext = session.typeContext
|
||||
private val context = session.typeContext
|
||||
|
||||
private fun isEqualTypes(substitutedCandidateType: ConeKotlinType, substitutedBaseType: ConeKotlinType): Boolean {
|
||||
return with(context) {
|
||||
@@ -45,16 +45,11 @@ class FirStandardOverrideChecker(private val session: FirSession) : FirAbstractO
|
||||
}
|
||||
|
||||
private fun isEqualTypes(candidateType: ConeKotlinType, baseType: ConeKotlinType, substitutor: ConeSubstitutor): Boolean {
|
||||
val substitutedCandidateType = substitutor.substituteOrSelf(candidateType).unwrapDefinitelyNotNullType()
|
||||
val substitutedBaseType = substitutor.substituteOrSelf(baseType).unwrapDefinitelyNotNullType()
|
||||
val substitutedCandidateType = substitutor.substituteOrSelf(candidateType)
|
||||
val substitutedBaseType = substitutor.substituteOrSelf(baseType)
|
||||
return isEqualTypes(substitutedCandidateType, substitutedBaseType)
|
||||
}
|
||||
|
||||
private fun ConeKotlinType.unwrapDefinitelyNotNullType(): ConeKotlinType = when (this) {
|
||||
is ConeDefinitelyNotNullType -> original
|
||||
else -> this
|
||||
}
|
||||
|
||||
fun isEqualTypes(candidateTypeRef: FirTypeRef, baseTypeRef: FirTypeRef, substitutor: ConeSubstitutor): Boolean {
|
||||
candidateTypeRef.ensureResolvedTypeDeclaration(session, requiredPhase = FirResolvePhase.TYPES)
|
||||
baseTypeRef.ensureResolvedTypeDeclaration(session, requiredPhase = FirResolvePhase.TYPES)
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ interface B<T1> : A<T1> {
|
||||
|
||||
interface C<T2> : A<T2> {
|
||||
override fun foo(x: T2 & Any): T2 & Any
|
||||
override fun bar(x: T2): <!RETURN_TYPE_MISMATCH_ON_OVERRIDE!>T2<!>
|
||||
<!NOTHING_TO_OVERRIDE!>override<!> fun bar(x: T2): T2
|
||||
}
|
||||
|
||||
interface D : A<String?> {
|
||||
|
||||
@@ -82,6 +82,13 @@ FILE fqName:<root> fileName:/AbstractMutableMap.kt
|
||||
VALUE_PARAMETER name:p0 index:0 type:K of <root>.MyMap
|
||||
VALUE_PARAMETER name:p1 index:1 type:@[EnhancedNullability] V of <root>.MyMap
|
||||
VALUE_PARAMETER name:p2 index:2 type:@[EnhancedNullability] java.util.function.BiFunction<in @[FlexibleNullability] V of <root>.MyMap?, in @[FlexibleNullability] V of <root>.MyMap?, out @[FlexibleNullability] V of <root>.MyMap?>
|
||||
FUN FAKE_OVERRIDE name:merge visibility:public modality:OPEN <> ($this:kotlin.collections.MutableMap<K of kotlin.collections.MutableMap, V of kotlin.collections.MutableMap>, p0:@[FlexibleNullability] K of <root>.MyMap?, p1:V of <root>.MyMap, p2:@[EnhancedNullability] java.util.function.BiFunction<in @[FlexibleNullability] V of <root>.MyMap?, in @[FlexibleNullability] V of <root>.MyMap?, out @[FlexibleNullability] V of <root>.MyMap?>) returnType:V of <root>.MyMap? [fake_override]
|
||||
overridden:
|
||||
public open fun merge (p0: @[FlexibleNullability] K of kotlin.collections.AbstractMutableMap?, p1: V of kotlin.collections.AbstractMutableMap, p2: @[EnhancedNullability] java.util.function.BiFunction<in @[FlexibleNullability] V of kotlin.collections.AbstractMutableMap?, in @[FlexibleNullability] V of kotlin.collections.AbstractMutableMap?, out @[FlexibleNullability] V of kotlin.collections.AbstractMutableMap?>): V of kotlin.collections.AbstractMutableMap? [fake_override] declared in kotlin.collections.AbstractMutableMap
|
||||
$this: VALUE_PARAMETER name:<this> type:kotlin.collections.MutableMap<K of kotlin.collections.MutableMap, V of kotlin.collections.MutableMap>
|
||||
VALUE_PARAMETER name:p0 index:0 type:@[FlexibleNullability] K of <root>.MyMap?
|
||||
VALUE_PARAMETER name:p1 index:1 type:V of <root>.MyMap
|
||||
VALUE_PARAMETER name:p2 index:2 type:@[EnhancedNullability] java.util.function.BiFunction<in @[FlexibleNullability] V of <root>.MyMap?, in @[FlexibleNullability] V of <root>.MyMap?, out @[FlexibleNullability] V of <root>.MyMap?>
|
||||
FUN FAKE_OVERRIDE name:computeIfPresent visibility:public modality:OPEN <> ($this:kotlin.collections.MutableMap<K of kotlin.collections.MutableMap, V of kotlin.collections.MutableMap>, p0:K of <root>.MyMap, p1:@[EnhancedNullability] java.util.function.BiFunction<in @[FlexibleNullability] K of <root>.MyMap?, in @[FlexibleNullability] V of <root>.MyMap?, out @[FlexibleNullability] V of <root>.MyMap?>) returnType:V of <root>.MyMap? [fake_override]
|
||||
overridden:
|
||||
public open fun computeIfPresent (p0: K of kotlin.collections.AbstractMutableMap, p1: @[EnhancedNullability] java.util.function.BiFunction<in @[FlexibleNullability] K of kotlin.collections.AbstractMutableMap?, in @[FlexibleNullability] V of kotlin.collections.AbstractMutableMap?, out @[FlexibleNullability] V of kotlin.collections.AbstractMutableMap?>): V of kotlin.collections.AbstractMutableMap? [fake_override] declared in kotlin.collections.AbstractMutableMap
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
@OptIn(markerClass = [ExperimentalTypeInference::class])
|
||||
fun <R : Any?> scopedFlow(@BuilderInference block: @ExtensionFunctionType SuspendFunction2<CoroutineScope, FlowCollector<R>, Unit>): Flow<R> {
|
||||
return flow<R>(block = local suspend fun FlowCollector<R>.<anonymous>() {
|
||||
val collector: FlowCollector<Nothing> = <this>
|
||||
val collector: FlowCollector<R> = <this>
|
||||
flowScope<Unit>(block = local suspend fun CoroutineScope.<anonymous>() {
|
||||
block.invoke(p1 = <this>, p2 = collector)
|
||||
}
|
||||
@@ -12,7 +12,7 @@ fun <R : Any?> scopedFlow(@BuilderInference block: @ExtensionFunctionType Suspen
|
||||
|
||||
fun <T : Any?> Flow<T>.onCompletion(action: @ExtensionFunctionType SuspendFunction2<FlowCollector<T>, Throwable?, Unit>): Flow<T> {
|
||||
return unsafeFlow<T>(block = local suspend fun FlowCollector<T>.<anonymous>() {
|
||||
val safeCollector: SafeCollector<Any?> = SafeCollector<T>(collector = <this>)
|
||||
val safeCollector: SafeCollector<T> = SafeCollector<T>(collector = <this>)
|
||||
safeCollector.invokeSafely<T>(action = action)
|
||||
}
|
||||
)
|
||||
@@ -27,11 +27,11 @@ inline fun <T : Any?> unsafeFlow(@BuilderInference crossinline block: @Extension
|
||||
}
|
||||
|
||||
@Deprecated(message = "binary compatibility with a version w/o FlowCollector receiver", level = DeprecationLevel.HIDDEN)
|
||||
fun <T : Any?> Flow<T>.onCompletion(action: SuspendFunction1<Throwable?, Unit>): ErrorType {
|
||||
return error("") /* ErrorCallExpression */local fun <anonymous>() {
|
||||
action.invoke(p1 = error("") /* ErrorCallExpression */)
|
||||
fun <T : Any?> Flow<T>.onCompletion(action: SuspendFunction1<Throwable?, Unit>): Flow<T> {
|
||||
return <this>.onCompletion<T>(action = local suspend fun FlowCollector<T>.<anonymous>(it: Throwable?) {
|
||||
action.invoke(p1 = it)
|
||||
}
|
||||
;
|
||||
)
|
||||
}
|
||||
|
||||
private fun CoroutineScope.asFairChannel(flow: Flow<*>): ReceiveChannel<Any> {
|
||||
@@ -113,12 +113,12 @@ interface CoroutineScope {
|
||||
}
|
||||
|
||||
interface Flow<out T : Any?> {
|
||||
abstract suspend fun collect(collector: FlowCollector<T>)
|
||||
abstract suspend fun collect(collector: FlowCollector<T>)
|
||||
|
||||
}
|
||||
|
||||
interface FlowCollector<in T : Any?> {
|
||||
abstract suspend fun emit(value: T)
|
||||
abstract suspend fun emit(value: T)
|
||||
|
||||
}
|
||||
|
||||
@@ -138,7 +138,7 @@ interface ProducerScope<in E : Any?> : CoroutineScope, SendChannel<E> {
|
||||
}
|
||||
|
||||
interface SendChannel<in E : Any?> {
|
||||
abstract suspend fun send(e: E)
|
||||
abstract suspend fun send(e: E)
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -14,8 +14,8 @@ FILE fqName:<root> fileName:/castsInsideCoroutineInference.kt
|
||||
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> ($receiver:<root>.FlowCollector<R of <root>.scopedFlow>) returnType:kotlin.Unit [suspend]
|
||||
$receiver: VALUE_PARAMETER name:<this> type:<root>.FlowCollector<R of <root>.scopedFlow>
|
||||
BLOCK_BODY
|
||||
VAR name:collector type:<root>.FlowCollector<kotlin.Nothing> [val]
|
||||
GET_VAR '<this>: <root>.FlowCollector<R of <root>.scopedFlow> declared in <root>.scopedFlow.<anonymous>' type=<root>.FlowCollector<kotlin.Nothing> origin=null
|
||||
VAR name:collector type:<root>.FlowCollector<R of <root>.scopedFlow> [val]
|
||||
GET_VAR '<this>: <root>.FlowCollector<R of <root>.scopedFlow> declared in <root>.scopedFlow.<anonymous>' type=<root>.FlowCollector<R of <root>.scopedFlow> origin=null
|
||||
CALL 'public final fun flowScope <R> (block: @[ExtensionFunctionType] kotlin.coroutines.SuspendFunction1<<root>.CoroutineScope, R of <root>.flowScope>): R of <root>.flowScope [suspend] declared in <root>' type=kotlin.Unit origin=null
|
||||
<R>: kotlin.Unit
|
||||
block: FUN_EXPR type=kotlin.coroutines.SuspendFunction1<<root>.CoroutineScope, kotlin.Unit> origin=LAMBDA
|
||||
@@ -25,7 +25,7 @@ FILE fqName:<root> fileName:/castsInsideCoroutineInference.kt
|
||||
CALL 'public abstract fun invoke (p1: P1 of kotlin.coroutines.SuspendFunction2, p2: P2 of kotlin.coroutines.SuspendFunction2): R of kotlin.coroutines.SuspendFunction2 [suspend,operator] declared in kotlin.coroutines.SuspendFunction2' type=kotlin.Unit origin=null
|
||||
$this: GET_VAR 'block: @[ExtensionFunctionType] kotlin.coroutines.SuspendFunction2<<root>.CoroutineScope, <root>.FlowCollector<R of <root>.scopedFlow>, kotlin.Unit> declared in <root>.scopedFlow' type=@[ExtensionFunctionType] kotlin.coroutines.SuspendFunction2<<root>.CoroutineScope, <root>.FlowCollector<R of <root>.scopedFlow>, kotlin.Unit> origin=VARIABLE_AS_FUNCTION
|
||||
p1: GET_VAR '<this>: <root>.CoroutineScope declared in <root>.scopedFlow.<anonymous>.<anonymous>' type=<root>.CoroutineScope origin=null
|
||||
p2: GET_VAR 'val collector: <root>.FlowCollector<kotlin.Nothing> [val] declared in <root>.scopedFlow.<anonymous>' type=<root>.FlowCollector<R of <root>.scopedFlow> origin=null
|
||||
p2: GET_VAR 'val collector: <root>.FlowCollector<R of <root>.scopedFlow> [val] declared in <root>.scopedFlow.<anonymous>' type=<root>.FlowCollector<R of <root>.scopedFlow> origin=null
|
||||
FUN name:onCompletion visibility:public modality:FINAL <T> ($receiver:<root>.Flow<T of <root>.onCompletion>, action:@[ExtensionFunctionType] kotlin.coroutines.SuspendFunction2<<root>.FlowCollector<T of <root>.onCompletion>, kotlin.Throwable?, kotlin.Unit>) returnType:<root>.Flow<T of <root>.onCompletion>
|
||||
TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.Any?]
|
||||
$receiver: VALUE_PARAMETER name:<this> type:<root>.Flow<T of <root>.onCompletion>
|
||||
@@ -38,13 +38,13 @@ FILE fqName:<root> fileName:/castsInsideCoroutineInference.kt
|
||||
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> ($receiver:<root>.FlowCollector<T of <root>.onCompletion>) returnType:kotlin.Unit [suspend]
|
||||
$receiver: VALUE_PARAMETER name:<this> type:<root>.FlowCollector<T of <root>.onCompletion>
|
||||
BLOCK_BODY
|
||||
VAR name:safeCollector type:<root>.SafeCollector<kotlin.Any?> [val]
|
||||
VAR name:safeCollector type:<root>.SafeCollector<T of <root>.onCompletion> [val]
|
||||
CONSTRUCTOR_CALL 'public constructor <init> (collector: <root>.FlowCollector<T of <root>.SafeCollector>) [primary] declared in <root>.SafeCollector' type=<root>.SafeCollector<T of <root>.onCompletion> origin=null
|
||||
<class: T>: T of <root>.onCompletion
|
||||
collector: GET_VAR '<this>: <root>.FlowCollector<T of <root>.onCompletion> declared in <root>.onCompletion.<anonymous>' type=<root>.FlowCollector<T of <root>.onCompletion> origin=null
|
||||
CALL 'public final fun invokeSafely <T> (action: @[ExtensionFunctionType] kotlin.coroutines.SuspendFunction2<<root>.FlowCollector<T of <root>.invokeSafely>, kotlin.Throwable?, kotlin.Unit>): kotlin.Unit [suspend] declared in <root>' type=kotlin.Unit origin=null
|
||||
<T>: T of <root>.onCompletion
|
||||
$receiver: GET_VAR 'val safeCollector: <root>.SafeCollector<kotlin.Any?> [val] declared in <root>.onCompletion.<anonymous>' type=<root>.SafeCollector<T of <root>.onCompletion> origin=null
|
||||
$receiver: GET_VAR 'val safeCollector: <root>.SafeCollector<T of <root>.onCompletion> [val] declared in <root>.onCompletion.<anonymous>' type=<root>.SafeCollector<T of <root>.onCompletion> origin=null
|
||||
action: GET_VAR 'action: @[ExtensionFunctionType] kotlin.coroutines.SuspendFunction2<<root>.FlowCollector<T of <root>.onCompletion>, kotlin.Throwable?, kotlin.Unit> declared in <root>.onCompletion' type=@[ExtensionFunctionType] kotlin.coroutines.SuspendFunction2<<root>.FlowCollector<T of <root>.onCompletion>, kotlin.Throwable?, kotlin.Unit> origin=null
|
||||
FUN name:invokeSafely visibility:public modality:FINAL <T> ($receiver:<root>.FlowCollector<T of <root>.invokeSafely>, action:@[ExtensionFunctionType] kotlin.coroutines.SuspendFunction2<<root>.FlowCollector<T of <root>.invokeSafely>, kotlin.Throwable?, kotlin.Unit>) returnType:kotlin.Unit [suspend]
|
||||
TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.Any?]
|
||||
@@ -61,21 +61,25 @@ FILE fqName:<root> fileName:/castsInsideCoroutineInference.kt
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun unsafeFlow <T> (block: @[ExtensionFunctionType] kotlin.coroutines.SuspendFunction1<<root>.FlowCollector<T of <root>.unsafeFlow>, kotlin.Unit>): <root>.Flow<T of <root>.unsafeFlow> [inline] declared in <root>'
|
||||
CALL 'public final fun TODO (): kotlin.Nothing [inline] declared in kotlin.StandardKt' type=kotlin.Nothing origin=null
|
||||
FUN name:onCompletion visibility:public modality:FINAL <T> ($receiver:<root>.Flow<T of <root>.onCompletion>, action:kotlin.coroutines.SuspendFunction1<kotlin.Throwable?, kotlin.Unit>) returnType:IrErrorType(null)
|
||||
FUN name:onCompletion visibility:public modality:FINAL <T> ($receiver:<root>.Flow<T of <root>.onCompletion>, action:kotlin.coroutines.SuspendFunction1<kotlin.Throwable?, kotlin.Unit>) returnType:<root>.Flow<T of <root>.onCompletion>
|
||||
annotations:
|
||||
Deprecated(message = 'binary compatibility with a version w/o FlowCollector receiver', replaceWith = <null>, level = GET_ENUM 'ENUM_ENTRY IR_EXTERNAL_DECLARATION_STUB name:HIDDEN' type=kotlin.DeprecationLevel)
|
||||
TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.Any?]
|
||||
$receiver: VALUE_PARAMETER name:<this> type:<root>.Flow<T of <root>.onCompletion>
|
||||
VALUE_PARAMETER name:action index:0 type:kotlin.coroutines.SuspendFunction1<kotlin.Throwable?, kotlin.Unit>
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun onCompletion <T> (action: kotlin.coroutines.SuspendFunction1<kotlin.Throwable?, kotlin.Unit>): IrErrorType(null) declared in <root>'
|
||||
ERROR_CALL 'Unresolved reference: <Ambiguity: onCompletion, [/onCompletion, /onCompletion]>#' type=IrErrorType(null)
|
||||
FUN_EXPR type=kotlin.Function0<kotlin.Unit> origin=LAMBDA
|
||||
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> () returnType:kotlin.Unit
|
||||
RETURN type=kotlin.Nothing from='public final fun onCompletion <T> (action: kotlin.coroutines.SuspendFunction1<kotlin.Throwable?, kotlin.Unit>): <root>.Flow<T of <root>.onCompletion> declared in <root>'
|
||||
CALL 'public final fun onCompletion <T> (action: @[ExtensionFunctionType] kotlin.coroutines.SuspendFunction2<<root>.FlowCollector<T of <root>.onCompletion>, kotlin.Throwable?, kotlin.Unit>): <root>.Flow<T of <root>.onCompletion> declared in <root>' type=<root>.Flow<T of <root>.onCompletion> origin=null
|
||||
<T>: T of <root>.onCompletion
|
||||
$receiver: GET_VAR '<this>: <root>.Flow<T of <root>.onCompletion> declared in <root>.onCompletion' type=<root>.Flow<T of <root>.onCompletion> origin=null
|
||||
action: FUN_EXPR type=kotlin.coroutines.SuspendFunction2<<root>.FlowCollector<T of <root>.onCompletion>, kotlin.Throwable?, kotlin.Unit> origin=LAMBDA
|
||||
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> ($receiver:<root>.FlowCollector<T of <root>.onCompletion>, it:kotlin.Throwable?) returnType:kotlin.Unit [suspend]
|
||||
$receiver: VALUE_PARAMETER name:<this> type:<root>.FlowCollector<T of <root>.onCompletion>
|
||||
VALUE_PARAMETER name:it index:0 type:kotlin.Throwable?
|
||||
BLOCK_BODY
|
||||
CALL 'public abstract fun invoke (p1: P1 of kotlin.coroutines.SuspendFunction1): R of kotlin.coroutines.SuspendFunction1 [suspend,operator] declared in kotlin.coroutines.SuspendFunction1' type=kotlin.Unit origin=null
|
||||
$this: GET_VAR 'action: kotlin.coroutines.SuspendFunction1<kotlin.Throwable?, kotlin.Unit> declared in <root>.onCompletion' type=kotlin.coroutines.SuspendFunction1<kotlin.Throwable?, kotlin.Unit> origin=VARIABLE_AS_FUNCTION
|
||||
p1: ERROR_CALL 'Unresolved reference: <Unresolved name: it>#' type=IrErrorType(null)
|
||||
p1: GET_VAR 'it: kotlin.Throwable? declared in <root>.onCompletion.<anonymous>' type=kotlin.Throwable? origin=null
|
||||
FUN name:asFairChannel visibility:private modality:FINAL <> ($receiver:<root>.CoroutineScope, flow:<root>.Flow<*>) returnType:<root>.ReceiveChannel<kotlin.Any>
|
||||
$receiver: VALUE_PARAMETER name:<this> type:<root>.CoroutineScope
|
||||
VALUE_PARAMETER name:flow index:0 type:<root>.Flow<*>
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// !LANGUAGE: +NewInference
|
||||
// WITH_RUNTIME
|
||||
|
||||
@@ -84,4 +83,4 @@ interface ProducerScope<in E> : CoroutineScope, SendChannel<E> {
|
||||
|
||||
interface SendChannel<in E> {
|
||||
suspend fun send(e: E)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user