Rework checking constraints by presented OnlyInputTypes annotation in accordance with changed incorporation mechanism

This commit is contained in:
Victor Petukhov
2020-11-19 12:42:04 +03:00
parent 0857b9c9e7
commit 04846ca47a
9 changed files with 86 additions and 20 deletions
@@ -271,6 +271,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/annotations/typeAnnotations"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
}
@TestMetadata("checkingNotincorporatedInputTypes.kt")
public void testCheckingNotincorporatedInputTypes() throws Exception {
runTest("compiler/testData/codegen/box/annotations/typeAnnotations/checkingNotincorporatedInputTypes.kt");
}
@TestMetadata("implicitReturn.kt")
public void testImplicitReturn() throws Exception {
runTest("compiler/testData/codegen/box/annotations/typeAnnotations/implicitReturn.kt");
@@ -28,6 +28,8 @@ class NewConstraintSystemImpl(
{
private val utilContext = constraintInjector.constraintIncorporator.utilContext
private val postponedComputationsAfterAllVariablesAreFixed = mutableListOf<() -> Unit>()
private val storage = MutableConstraintStorage()
private var state = State.BUILDING
private val typeVariablesTransaction: MutableList<TypeVariableMarker> = SmartList()
@@ -321,42 +323,65 @@ class NewConstraintSystemImpl(
}
// KotlinConstraintSystemCompleter.Context
// TODO: simplify this: do only substitution a fixing type variable rather than running of subtyping and full incorporation
override fun fixVariable(variable: TypeVariableMarker, resultType: KotlinTypeMarker, position: FixVariableConstraintPosition<*>) {
override fun fixVariable(
variable: TypeVariableMarker,
resultType: KotlinTypeMarker,
position: FixVariableConstraintPosition<*>
) = with(utilContext) {
checkState(State.BUILDING, State.COMPLETION)
constraintInjector.addInitialEqualityConstraint(
this, variable.defaultType(), resultType, position
)
constraintInjector.addInitialEqualityConstraint(this@NewConstraintSystemImpl, variable.defaultType(), resultType, position)
val freshTypeConstructor = variable.freshTypeConstructor()
val variableWithConstraints = notFixedTypeVariables.remove(freshTypeConstructor)
checkOnlyInputTypesAnnotation(variableWithConstraints, resultType)
for (variableWithConstraint in notFixedTypeVariables.values) {
variableWithConstraint.removeConstrains {
it.type.contains { it.typeConstructor() == freshTypeConstructor }
for (otherVariableWithConstraints in notFixedTypeVariables.values) {
otherVariableWithConstraints.removeConstrains { otherConstraint ->
otherConstraint.type.contains { it.typeConstructor() == freshTypeConstructor }
}
}
storage.fixedTypeVariables[freshTypeConstructor] = resultType
postponeOnlyInputTypesCheck(variableWithConstraints, resultType)
doPostponedComputationsIfAllVariablesAreFixed()
}
private fun checkOnlyInputTypesAnnotation(
private fun ConstraintSystemUtilContext.postponeOnlyInputTypesCheck(
variableWithConstraints: MutableVariableWithConstraints?,
resultType: KotlinTypeMarker
) {
if (variableWithConstraints == null) return
val variableHasOnlyInputTypes = with(utilContext) { variableWithConstraints.typeVariable.hasOnlyInputTypesAttribute() }
if (!variableHasOnlyInputTypes) return
val resultTypeIsInputType = variableWithConstraints.getProjectedInputCallTypes(utilContext).any { inputType ->
if (AbstractTypeChecker.equalTypes(this, resultType, inputType)) return@any true
val constructor = inputType.typeConstructor()
constructor.isIntersection() && constructor.supertypes().any { AbstractTypeChecker.equalTypes(this, resultType, it) }
if (variableWithConstraints != null && variableWithConstraints.typeVariable.hasOnlyInputTypesAttribute()) {
postponedComputationsAfterAllVariablesAreFixed.add { checkOnlyInputTypesAnnotation(variableWithConstraints, resultType) }
}
if (!resultTypeIsInputType) {
}
private fun doPostponedComputationsIfAllVariablesAreFixed() {
if (notFixedTypeVariables.isEmpty()) {
postponedComputationsAfterAllVariablesAreFixed.forEach { it() }
}
}
private fun KotlinTypeMarker.substituteIfNecessary(substitutor: TypeSubstitutorMarker): KotlinTypeMarker {
val doesInputTypeContainsOtherVariables = this.contains { it.typeConstructor() is TypeVariableTypeConstructorMarker }
return if (doesInputTypeContainsOtherVariables) substitutor.safeSubstitute(this) else this
}
private fun checkOnlyInputTypesAnnotation(variableWithConstraints: MutableVariableWithConstraints, resultType: KotlinTypeMarker) {
val substitutor = buildCurrentSubstitutor()
val isResultTypeEqualSomeInputType = variableWithConstraints.getProjectedInputCallTypes(utilContext).any { inputType ->
val inputTypeConstructor = inputType.typeConstructor()
if (inputTypeConstructor.isIntersection()) {
inputTypeConstructor.supertypes().any {
AbstractTypeChecker.equalTypes(this, resultType, it.substituteIfNecessary(substitutor))
}
} else {
AbstractTypeChecker.equalTypes(this, resultType, inputType.substituteIfNecessary(substitutor))
}
}
if (!isResultTypeEqualSomeInputType) {
addError(OnlyInputTypesDiagnostic(variableWithConstraints.typeVariable))
}
}
@@ -0,0 +1,6 @@
// IGNORE_BACKEND: JS_IR
// WITH_RUNTIME
fun isImportedByDefault(c: String?, x: Set<Int>) = c?.let { it.toInt() } in x
fun box(): String = "OK"
@@ -271,6 +271,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/annotations/typeAnnotations"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
}
@TestMetadata("checkingNotincorporatedInputTypes.kt")
public void testCheckingNotincorporatedInputTypes() throws Exception {
runTest("compiler/testData/codegen/box/annotations/typeAnnotations/checkingNotincorporatedInputTypes.kt");
}
@TestMetadata("implicitReturn.kt")
public void testImplicitReturn() throws Exception {
runTest("compiler/testData/codegen/box/annotations/typeAnnotations/implicitReturn.kt");
@@ -271,6 +271,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/annotations/typeAnnotations"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
}
@TestMetadata("checkingNotincorporatedInputTypes.kt")
public void testCheckingNotincorporatedInputTypes() throws Exception {
runTest("compiler/testData/codegen/box/annotations/typeAnnotations/checkingNotincorporatedInputTypes.kt");
}
@TestMetadata("implicitReturn.kt")
public void testImplicitReturn() throws Exception {
runTest("compiler/testData/codegen/box/annotations/typeAnnotations/implicitReturn.kt");
@@ -85,6 +85,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes
public void testAllFilesPresentInTypeAnnotations() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/annotations/typeAnnotations"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR_ES6, true);
}
@TestMetadata("checkingNotincorporatedInputTypes.kt")
public void testCheckingNotincorporatedInputTypes() throws Exception {
runTest("compiler/testData/codegen/box/annotations/typeAnnotations/checkingNotincorporatedInputTypes.kt");
}
}
}
@@ -85,6 +85,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
public void testAllFilesPresentInTypeAnnotations() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/annotations/typeAnnotations"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true);
}
@TestMetadata("checkingNotincorporatedInputTypes.kt")
public void testCheckingNotincorporatedInputTypes() throws Exception {
runTest("compiler/testData/codegen/box/annotations/typeAnnotations/checkingNotincorporatedInputTypes.kt");
}
}
}
@@ -85,6 +85,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
public void testAllFilesPresentInTypeAnnotations() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/annotations/typeAnnotations"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true);
}
@TestMetadata("checkingNotincorporatedInputTypes.kt")
public void testCheckingNotincorporatedInputTypes() throws Exception {
runTest("compiler/testData/codegen/box/annotations/typeAnnotations/checkingNotincorporatedInputTypes.kt");
}
}
}
@@ -80,6 +80,11 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest
public void testAllFilesPresentInTypeAnnotations() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/annotations/typeAnnotations"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.WASM, true);
}
@TestMetadata("checkingNotincorporatedInputTypes.kt")
public void testCheckingNotincorporatedInputTypes() throws Exception {
runTest("compiler/testData/codegen/box/annotations/typeAnnotations/checkingNotincorporatedInputTypes.kt");
}
}
}