FIR DFA: revalidate reassigned variables after loops

If a certain type statement is true on loop entry and all continue
paths, then it is also true on exit if the condition did not reassign
the variable.

^KT-7676 tag fixed-in-k2
This commit is contained in:
pyos
2022-11-14 16:40:41 +01:00
committed by teamcity
parent f9745bd3f1
commit 02fedeb9ed
8 changed files with 83 additions and 59 deletions
@@ -21,7 +21,6 @@ abstract class LogicSystem<FLOW : Flow>(protected val context: ConeInferenceCont
abstract fun addImplication(flow: FLOW, implication: Implication)
abstract fun addLocalVariableAlias(flow: FLOW, alias: RealVariable, underlyingVariable: RealVariable)
abstract fun recordNewAssignment(flow: FLOW, variable: RealVariable, index: Int)
abstract fun removeAllAboutVariable(flow: FLOW, variable: RealVariable)
abstract fun copyAllInformation(from: FLOW, to: FLOW)
abstract fun isSameValueIn(a: FLOW, b: FLOW, variable: RealVariable): Boolean
@@ -91,9 +90,9 @@ abstract class LogicSystem<FLOW : Flow>(protected val context: ConeInferenceCont
exactType += other.exactType
}
protected fun and(statements: Collection<TypeStatement>): TypeStatement? =
fun and(statements: Collection<TypeStatement>): TypeStatement? =
statements.singleOrNew { statements.flatMapTo(mutableSetOf()) { it.exactType } }
protected fun or(statements: Collection<TypeStatement>): TypeStatement? =
fun or(statements: Collection<TypeStatement>): TypeStatement? =
statements.singleOrNew { unifyTypes(statements.map { it.exactType })?.let { mutableSetOf(it) } ?: mutableSetOf() }
}
@@ -165,10 +165,6 @@ abstract class PersistentLogicSystem(context: ConeInferenceContext) : LogicSyste
flow.addAliases(persistentSetOf(alias), flow.unwrapVariable(underlyingVariable))
}
override fun removeAllAboutVariable(flow: PersistentFlow, variable: RealVariable) {
flow.replaceVariable(variable, null)
}
private fun PersistentFlow.replaceVariable(variable: RealVariable, replacement: RealVariable?) {
val original = directAliasMap[variable]
if (original != null) {
@@ -320,7 +316,7 @@ abstract class PersistentLogicSystem(context: ConeInferenceContext) : LogicSyste
}
override fun recordNewAssignment(flow: PersistentFlow, variable: RealVariable, index: Int) {
removeAllAboutVariable(flow, variable)
flow.replaceVariable(variable, null)
flow.assignmentIndex = flow.assignmentIndex.put(variable, index)
}