[NI] Don't try inferring variables for effectively empty system
This commit is contained in:
+22
-10
@@ -109,14 +109,12 @@ class CoroutineInferenceSession(
|
|||||||
initialStorage: ConstraintStorage,
|
initialStorage: ConstraintStorage,
|
||||||
diagnosticsHolder: KotlinDiagnosticsHolder
|
diagnosticsHolder: KotlinDiagnosticsHolder
|
||||||
): Map<TypeConstructor, UnwrappedType>? {
|
): Map<TypeConstructor, UnwrappedType>? {
|
||||||
if (partiallyResolvedCallsInfo.isEmpty() && commonCalls.isEmpty()) {
|
val (commonSystem, effectivelyEmptyConstraintSystem) = buildCommonSystem(initialStorage)
|
||||||
val emptyCommonSystem = NewConstraintSystemImpl(callComponents.constraintInjector, builtIns)
|
if (effectivelyEmptyConstraintSystem) {
|
||||||
updateCalls(lambda, emptyCommonSystem)
|
updateCalls(lambda, commonSystem)
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
val commonSystem = buildCommonSystem(initialStorage)
|
|
||||||
|
|
||||||
val context = commonSystem.asConstraintSystemCompleterContext()
|
val context = commonSystem.asConstraintSystemCompleterContext()
|
||||||
kotlinConstraintSystemCompleter.completeConstraintSystem(
|
kotlinConstraintSystemCompleter.completeConstraintSystem(
|
||||||
context,
|
context,
|
||||||
@@ -146,7 +144,7 @@ class CoroutineInferenceSession(
|
|||||||
storage: ConstraintStorage,
|
storage: ConstraintStorage,
|
||||||
nonFixedToVariablesSubstitutor: NewTypeSubstitutor,
|
nonFixedToVariablesSubstitutor: NewTypeSubstitutor,
|
||||||
shouldIntegrateAllConstraints: Boolean
|
shouldIntegrateAllConstraints: Boolean
|
||||||
) {
|
): Boolean {
|
||||||
storage.notFixedTypeVariables.values.forEach { commonSystem.registerVariable(it.typeVariable) }
|
storage.notFixedTypeVariables.values.forEach { commonSystem.registerVariable(it.typeVariable) }
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -158,12 +156,16 @@ class CoroutineInferenceSession(
|
|||||||
* */
|
* */
|
||||||
val callSubstitutor = storage.buildResultingSubstitutor(commonSystem, transformTypeVariablesToErrorTypes = false)
|
val callSubstitutor = storage.buildResultingSubstitutor(commonSystem, transformTypeVariablesToErrorTypes = false)
|
||||||
|
|
||||||
|
var introducedConstraint = false
|
||||||
|
|
||||||
for (initialConstraint in storage.initialConstraints) {
|
for (initialConstraint in storage.initialConstraints) {
|
||||||
val lower = nonFixedToVariablesSubstitutor.safeSubstitute(callSubstitutor.safeSubstitute(initialConstraint.a as UnwrappedType)) // TODO: SUB
|
val lower = nonFixedToVariablesSubstitutor.safeSubstitute(callSubstitutor.safeSubstitute(initialConstraint.a as UnwrappedType)) // TODO: SUB
|
||||||
val upper = nonFixedToVariablesSubstitutor.safeSubstitute(callSubstitutor.safeSubstitute(initialConstraint.b as UnwrappedType)) // TODO: SUB
|
val upper = nonFixedToVariablesSubstitutor.safeSubstitute(callSubstitutor.safeSubstitute(initialConstraint.b as UnwrappedType)) // TODO: SUB
|
||||||
|
|
||||||
if (commonSystem.isProperType(lower) && commonSystem.isProperType(upper)) continue
|
if (commonSystem.isProperType(lower) && commonSystem.isProperType(upper)) continue
|
||||||
|
|
||||||
|
introducedConstraint = true
|
||||||
|
|
||||||
when (initialConstraint.constraintKind) {
|
when (initialConstraint.constraintKind) {
|
||||||
ConstraintKind.LOWER -> error("LOWER constraint shouldn't be used, please use UPPER")
|
ConstraintKind.LOWER -> error("LOWER constraint shouldn't be used, please use UPPER")
|
||||||
|
|
||||||
@@ -182,28 +184,38 @@ class CoroutineInferenceSession(
|
|||||||
val typeVariable = storage.allTypeVariables.getValue(variableConstructor)
|
val typeVariable = storage.allTypeVariables.getValue(variableConstructor)
|
||||||
commonSystem.registerVariable(typeVariable)
|
commonSystem.registerVariable(typeVariable)
|
||||||
commonSystem.addEqualityConstraint((typeVariable as NewTypeVariable).defaultType, type, CoroutinePosition())
|
commonSystem.addEqualityConstraint((typeVariable as NewTypeVariable).defaultType, type, CoroutinePosition())
|
||||||
|
introducedConstraint = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return introducedConstraint
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun buildCommonSystem(initialStorage: ConstraintStorage): NewConstraintSystemImpl {
|
private fun buildCommonSystem(initialStorage: ConstraintStorage): Pair<NewConstraintSystemImpl, Boolean> {
|
||||||
val commonSystem = NewConstraintSystemImpl(callComponents.constraintInjector, builtIns)
|
val commonSystem = NewConstraintSystemImpl(callComponents.constraintInjector, builtIns)
|
||||||
|
|
||||||
val nonFixedToVariablesSubstitutor = createNonFixedTypeToVariableSubstitutor()
|
val nonFixedToVariablesSubstitutor = createNonFixedTypeToVariableSubstitutor()
|
||||||
|
|
||||||
integrateConstraints(commonSystem, initialStorage, nonFixedToVariablesSubstitutor, false)
|
integrateConstraints(commonSystem, initialStorage, nonFixedToVariablesSubstitutor, false)
|
||||||
|
|
||||||
|
var effectivelyEmptyCommonSystem = true
|
||||||
|
|
||||||
for (call in commonCalls) {
|
for (call in commonCalls) {
|
||||||
integrateConstraints(commonSystem, call.callResolutionResult.constraintSystem, nonFixedToVariablesSubstitutor, false)
|
val hasConstraints =
|
||||||
|
integrateConstraints(commonSystem, call.callResolutionResult.constraintSystem, nonFixedToVariablesSubstitutor, false)
|
||||||
|
if (hasConstraints) effectivelyEmptyCommonSystem = false
|
||||||
}
|
}
|
||||||
for (call in partiallyResolvedCallsInfo) {
|
for (call in partiallyResolvedCallsInfo) {
|
||||||
integrateConstraints(commonSystem, call.callResolutionResult.constraintSystem, nonFixedToVariablesSubstitutor, true)
|
val hasConstraints =
|
||||||
|
integrateConstraints(commonSystem, call.callResolutionResult.constraintSystem, nonFixedToVariablesSubstitutor, true)
|
||||||
|
if (hasConstraints) effectivelyEmptyCommonSystem = false
|
||||||
}
|
}
|
||||||
|
|
||||||
for (diagnostic in diagnostics) {
|
for (diagnostic in diagnostics) {
|
||||||
commonSystem.addError(diagnostic)
|
commonSystem.addError(diagnostic)
|
||||||
}
|
}
|
||||||
|
|
||||||
return commonSystem
|
return commonSystem to effectivelyEmptyCommonSystem
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateCalls(lambda: ResolvedLambdaAtom, commonSystem: NewConstraintSystemImpl) {
|
private fun updateCalls(lambda: ResolvedLambdaAtom, commonSystem: NewConstraintSystemImpl) {
|
||||||
|
|||||||
Vendored
+28
-1
@@ -12,7 +12,29 @@ fun test() {
|
|||||||
flow {
|
flow {
|
||||||
emit(1)
|
emit(1)
|
||||||
}.flatMapLatest<Int, Long> {
|
}.flatMapLatest<Int, Long> {
|
||||||
flow {}
|
flow {
|
||||||
|
expectInt(42)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
flow {
|
||||||
|
emit(1)
|
||||||
|
}.flatMapLatest<Int, Long> {
|
||||||
|
flow {
|
||||||
|
expectInt(42)
|
||||||
|
hang {
|
||||||
|
expectInt(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
flow {
|
||||||
|
emit(1)
|
||||||
|
}.flatMap {
|
||||||
|
if (it == 1)
|
||||||
|
flow { expectGeneric(42) }
|
||||||
|
else
|
||||||
|
flow<Int> {}
|
||||||
}
|
}
|
||||||
|
|
||||||
flow {
|
flow {
|
||||||
@@ -33,6 +55,11 @@ fun test() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun expectInt(i: Int) {}
|
||||||
|
fun <K> expectGeneric(i: K) {}
|
||||||
|
|
||||||
|
suspend inline fun hang(onCancellation: () -> Unit) {}
|
||||||
|
|
||||||
fun <T> Flow<T>.flatMap(mapper: suspend (T) -> Flow<T>): Flow<T> = TODO()
|
fun <T> Flow<T>.flatMap(mapper: suspend (T) -> Flow<T>): Flow<T> = TODO()
|
||||||
|
|
||||||
@OptIn(ExperimentalTypeInference::class)
|
@OptIn(ExperimentalTypeInference::class)
|
||||||
|
|||||||
Reference in New Issue
Block a user