[NI] Don't try inferring variables for effectively empty system

This commit is contained in:
Mikhail Zarechenskiy
2020-02-25 09:35:09 +03:00
parent fe71d5256c
commit 0b9fc1541d
2 changed files with 50 additions and 11 deletions
@@ -109,14 +109,12 @@ class CoroutineInferenceSession(
initialStorage: ConstraintStorage,
diagnosticsHolder: KotlinDiagnosticsHolder
): Map<TypeConstructor, UnwrappedType>? {
if (partiallyResolvedCallsInfo.isEmpty() && commonCalls.isEmpty()) {
val emptyCommonSystem = NewConstraintSystemImpl(callComponents.constraintInjector, builtIns)
updateCalls(lambda, emptyCommonSystem)
val (commonSystem, effectivelyEmptyConstraintSystem) = buildCommonSystem(initialStorage)
if (effectivelyEmptyConstraintSystem) {
updateCalls(lambda, commonSystem)
return null
}
val commonSystem = buildCommonSystem(initialStorage)
val context = commonSystem.asConstraintSystemCompleterContext()
kotlinConstraintSystemCompleter.completeConstraintSystem(
context,
@@ -146,7 +144,7 @@ class CoroutineInferenceSession(
storage: ConstraintStorage,
nonFixedToVariablesSubstitutor: NewTypeSubstitutor,
shouldIntegrateAllConstraints: Boolean
) {
): Boolean {
storage.notFixedTypeVariables.values.forEach { commonSystem.registerVariable(it.typeVariable) }
/*
@@ -158,12 +156,16 @@ class CoroutineInferenceSession(
* */
val callSubstitutor = storage.buildResultingSubstitutor(commonSystem, transformTypeVariablesToErrorTypes = false)
var introducedConstraint = false
for (initialConstraint in storage.initialConstraints) {
val lower = nonFixedToVariablesSubstitutor.safeSubstitute(callSubstitutor.safeSubstitute(initialConstraint.a as UnwrappedType)) // TODO: SUB
val upper = nonFixedToVariablesSubstitutor.safeSubstitute(callSubstitutor.safeSubstitute(initialConstraint.b as UnwrappedType)) // TODO: SUB
if (commonSystem.isProperType(lower) && commonSystem.isProperType(upper)) continue
introducedConstraint = true
when (initialConstraint.constraintKind) {
ConstraintKind.LOWER -> error("LOWER constraint shouldn't be used, please use UPPER")
@@ -182,28 +184,38 @@ class CoroutineInferenceSession(
val typeVariable = storage.allTypeVariables.getValue(variableConstructor)
commonSystem.registerVariable(typeVariable)
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 nonFixedToVariablesSubstitutor = createNonFixedTypeToVariableSubstitutor()
integrateConstraints(commonSystem, initialStorage, nonFixedToVariablesSubstitutor, false)
var effectivelyEmptyCommonSystem = true
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) {
integrateConstraints(commonSystem, call.callResolutionResult.constraintSystem, nonFixedToVariablesSubstitutor, true)
val hasConstraints =
integrateConstraints(commonSystem, call.callResolutionResult.constraintSystem, nonFixedToVariablesSubstitutor, true)
if (hasConstraints) effectivelyEmptyCommonSystem = false
}
for (diagnostic in diagnostics) {
commonSystem.addError(diagnostic)
}
return commonSystem
return commonSystem to effectivelyEmptyCommonSystem
}
private fun updateCalls(lambda: ResolvedLambdaAtom, commonSystem: NewConstraintSystemImpl) {
@@ -12,7 +12,29 @@ fun test() {
flow {
emit(1)
}.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 {
@@ -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()
@OptIn(ExperimentalTypeInference::class)