Disable slow assertions in type checker everywhere except for tests
This commit is contained in:
+12
-1
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.fir
|
||||
|
||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||
import org.jetbrains.kotlin.test.testFramework.KtUsefulTestCase
|
||||
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
||||
import org.w3c.dom.Node
|
||||
import org.w3c.dom.NodeList
|
||||
import java.io.File
|
||||
@@ -32,6 +33,16 @@ private fun NodeList.toList(): List<Node> {
|
||||
private val Node.childNodesList get() = childNodes.toList()
|
||||
|
||||
abstract class AbstractModularizedTest : KtUsefulTestCase() {
|
||||
override fun setUp() {
|
||||
super.setUp()
|
||||
AbstractTypeChecker.RUN_SLOW_ASSERTIONS = false
|
||||
}
|
||||
|
||||
override fun tearDown() {
|
||||
super.tearDown()
|
||||
AbstractTypeChecker.RUN_SLOW_ASSERTIONS = true
|
||||
}
|
||||
|
||||
private fun loadModule(file: File): ModuleData {
|
||||
|
||||
val factory = DocumentBuilderFactory.newInstance()
|
||||
@@ -92,4 +103,4 @@ abstract class AbstractModularizedTest : KtUsefulTestCase() {
|
||||
|
||||
afterPass()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -253,6 +253,7 @@ abstract class AbstractTypeCheckerContextForConstraintSystem : AbstractTypeCheck
|
||||
AbstractTypeChecker.isSubtypeOf(this as AbstractTypeCheckerContext, subType, superType)
|
||||
|
||||
private fun assertInputTypes(subType: KotlinTypeMarker, superType: KotlinTypeMarker) {
|
||||
if (!AbstractTypeChecker.RUN_SLOW_ASSERTIONS) return
|
||||
fun correctSubType(subType: SimpleTypeMarker) =
|
||||
subType.isSingleClassifierType() || subType.typeConstructor().isIntersection() || isMyTypeVariable(subType) || subType.isError() || subType.isIntegerLiteralType()
|
||||
|
||||
@@ -278,4 +279,4 @@ abstract class AbstractTypeCheckerContextForConstraintSystem : AbstractTypeCheck
|
||||
is FlexibleTypeMarker -> f(lowerBound()) || f(upperBound())
|
||||
else -> error("sealed")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+10
-8
@@ -88,13 +88,15 @@ interface NewTypeSubstitutor: TypeSubstitutorMarker {
|
||||
"original lower type: '${capturedType.lowerType}"
|
||||
)
|
||||
|
||||
typeConstructor.supertypes.forEach { supertype ->
|
||||
substitute(supertype, keepAnnotation, runCapturedChecks = false)?.let {
|
||||
throw IllegalStateException(
|
||||
"Illegal type substitutor: $this, " +
|
||||
"because for captured type '$type' supertype approximation should be null, but it is: '$supertype'," +
|
||||
"original supertype: '$supertype'"
|
||||
)
|
||||
if (AbstractTypeChecker.RUN_SLOW_ASSERTIONS) {
|
||||
typeConstructor.supertypes.forEach { supertype ->
|
||||
substitute(supertype, keepAnnotation, runCapturedChecks = false)?.let {
|
||||
throw IllegalStateException(
|
||||
"Illegal type substitutor: $this, " +
|
||||
"because for captured type '$type' supertype approximation should be null, but it is: '$supertype'," +
|
||||
"original supertype: '$supertype'"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,4 +180,4 @@ class FreshVariableNewTypeSubstitutor(val freshVariables: List<TypeVariableFromC
|
||||
fun UnwrappedType.substituteTypeVariable(typeVariable: NewTypeVariable, value: UnwrappedType): UnwrappedType {
|
||||
val substitutor = NewTypeSubstitutorByConstructorMap(mapOf(typeVariable.freshTypeConstructor to value))
|
||||
return substitutor.safeSubstitute(this)
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -16,8 +16,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.test.testFramework;
|
||||
|
||||
import com.intellij.codeInsight.CodeInsightSettings;
|
||||
import com.intellij.concurrency.IdeaForkJoinWorkerThreadFactory;
|
||||
import com.intellij.diagnostic.PerformanceWatcher;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.application.Application;
|
||||
@@ -51,6 +49,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.test.IdeaSystemPropertiesForParallelRunConfigurator;
|
||||
import org.jetbrains.kotlin.testFramework.MockComponentManagerCreationTracer;
|
||||
import org.jetbrains.kotlin.types.AbstractTypeChecker;
|
||||
import org.jetbrains.kotlin.types.FlexibleTypeImpl;
|
||||
import org.jetbrains.kotlin.utils.ExceptionUtilsKt;
|
||||
import org.junit.Assert;
|
||||
@@ -100,6 +99,7 @@ public abstract class KtUsefulTestCase extends TestCase {
|
||||
System.setProperty("apple.awt.UIElement", "true");
|
||||
|
||||
FlexibleTypeImpl.RUN_SLOW_ASSERTIONS = true;
|
||||
AbstractTypeChecker.RUN_SLOW_ASSERTIONS = true;
|
||||
}
|
||||
|
||||
protected boolean shouldContainTempFiles() {
|
||||
@@ -981,4 +981,4 @@ public abstract class KtUsefulTestCase extends TestCase {
|
||||
return KtUsefulTestCase.this.getClass() + (StringUtil.isEmpty(testName) ? "" : ".test" + testName);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
+23
-2
@@ -18,11 +18,15 @@ package org.jetbrains.kotlin.jvm.compiler
|
||||
|
||||
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
|
||||
import org.jetbrains.kotlin.test.KotlinTestWithEnvironmentManagement
|
||||
import org.jetbrains.kotlin.types.AbstractNullabilityChecker
|
||||
import org.jetbrains.kotlin.types.KotlinTypeFactory
|
||||
import org.jetbrains.kotlin.types.SimpleType
|
||||
import org.jetbrains.kotlin.types.TypeIntersector
|
||||
import org.jetbrains.kotlin.types.checker.ClassicTypeCheckerContext
|
||||
|
||||
class FlexibleTypeAssertionsEnabledTest : KotlinTestWithEnvironmentManagement() {
|
||||
class SlowTypeAssertionsEnabledTest : KotlinTestWithEnvironmentManagement() {
|
||||
|
||||
fun testAssertionsAreOn() {
|
||||
fun testAssertionsForFlexibleTypesAreOn() {
|
||||
val builtIns = DefaultBuiltIns.Instance
|
||||
|
||||
try {
|
||||
@@ -34,4 +38,21 @@ class FlexibleTypeAssertionsEnabledTest : KotlinTestWithEnvironmentManagement()
|
||||
|
||||
fail("Assertion error expected")
|
||||
}
|
||||
|
||||
fun testAssertionsForTypeCheckerAreOn() {
|
||||
val builtIns = DefaultBuiltIns.Instance
|
||||
|
||||
try {
|
||||
val superType = TypeIntersector.intersectTypes(listOf(builtIns.charSequence.defaultType, builtIns.comparable.defaultType))
|
||||
AbstractNullabilityChecker.isPossibleSubtype(
|
||||
ClassicTypeCheckerContext(errorTypeEqualsToAnything = true), builtIns.annotationType,
|
||||
superType as SimpleType
|
||||
)
|
||||
} catch (e: AssertionError) {
|
||||
assertEquals("Not singleClassifierType superType: {CharSequence & Comparable<T>}", e.message)
|
||||
return
|
||||
}
|
||||
|
||||
fail("Assertion error expected")
|
||||
}
|
||||
}
|
||||
@@ -144,6 +144,8 @@ abstract class AbstractTypeCheckerContext : TypeSystemContext {
|
||||
}
|
||||
|
||||
object AbstractTypeChecker {
|
||||
@JvmField
|
||||
var RUN_SLOW_ASSERTIONS = false
|
||||
|
||||
fun isSubtypeOf(context: TypeCheckerProviderContext, subType: KotlinTypeMarker, superType: KotlinTypeMarker): Boolean {
|
||||
return AbstractTypeChecker.isSubtypeOf(context.newBaseTypeCheckerContext(true), subType, superType)
|
||||
@@ -223,11 +225,13 @@ object AbstractTypeChecker {
|
||||
}
|
||||
|
||||
private fun AbstractTypeCheckerContext.isSubtypeOfForSingleClassifierType(subType: SimpleTypeMarker, superType: SimpleTypeMarker): Boolean {
|
||||
assert(subType.isSingleClassifierType() || subType.typeConstructor().isIntersection() || subType.isAllowedTypeVariable) {
|
||||
"Not singleClassifierType and not intersection subType: $subType"
|
||||
}
|
||||
assert(superType.isSingleClassifierType() || superType.isAllowedTypeVariable) {
|
||||
"Not singleClassifierType superType: $superType"
|
||||
if (AbstractTypeChecker.RUN_SLOW_ASSERTIONS) {
|
||||
assert(subType.isSingleClassifierType() || subType.typeConstructor().isIntersection() || subType.isAllowedTypeVariable) {
|
||||
"Not singleClassifierType and not intersection subType: $subType"
|
||||
}
|
||||
assert(superType.isSingleClassifierType() || superType.isAllowedTypeVariable) {
|
||||
"Not singleClassifierType superType: $superType"
|
||||
}
|
||||
}
|
||||
|
||||
if (!AbstractNullabilityChecker.isPossibleSubtype(this, subType, superType)) return false
|
||||
@@ -469,12 +473,14 @@ object AbstractNullabilityChecker {
|
||||
}
|
||||
|
||||
private fun AbstractTypeCheckerContext.runIsPossibleSubtype(subType: SimpleTypeMarker, superType: SimpleTypeMarker): Boolean {
|
||||
// it makes for case String? & Any <: String
|
||||
assert(subType.isSingleClassifierType() || subType.typeConstructor().isIntersection() || subType.isAllowedTypeVariable) {
|
||||
"Not singleClassifierType and not intersection subType: $subType"
|
||||
}
|
||||
assert(superType.isSingleClassifierType() || superType.isAllowedTypeVariable) {
|
||||
"Not singleClassifierType superType: $superType"
|
||||
if (AbstractTypeChecker.RUN_SLOW_ASSERTIONS) {
|
||||
// it makes for case String? & Any <: String
|
||||
assert(subType.isSingleClassifierType() || subType.typeConstructor().isIntersection() || subType.isAllowedTypeVariable) {
|
||||
"Not singleClassifierType and not intersection subType: $subType"
|
||||
}
|
||||
assert(superType.isSingleClassifierType() || superType.isAllowedTypeVariable) {
|
||||
"Not singleClassifierType superType: $superType"
|
||||
}
|
||||
}
|
||||
|
||||
// superType is actually nullable
|
||||
@@ -525,4 +531,4 @@ object AbstractNullabilityChecker {
|
||||
}) {
|
||||
if (it.isMarkedNullable()) SupertypesPolicy.None else SupertypesPolicy.LowerIfFlexible
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user