From 3d7d6e420471a1b98544e03e7c2fbaeceeb3cf20 Mon Sep 17 00:00:00 2001 From: Stanislav Erokhin Date: Thu, 29 Sep 2016 14:08:16 +0300 Subject: [PATCH] Fix EA-86841 and EA-79267. (cherry picked from commit fcf9bfd) --- .../types/AbstractClassTypeConstructor.java | 24 +++++++------- .../types/checker/TypeCheckingProcedure.java | 4 ++- .../jetbrains/kotlin/types/checker/utils.kt | 33 ++++++++++++++----- 3 files changed, 39 insertions(+), 22 deletions(-) diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/AbstractClassTypeConstructor.java b/core/descriptors/src/org/jetbrains/kotlin/types/AbstractClassTypeConstructor.java index 411b37874d0..238df26c26b 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/AbstractClassTypeConstructor.java +++ b/core/descriptors/src/org/jetbrains/kotlin/types/AbstractClassTypeConstructor.java @@ -30,8 +30,7 @@ import java.util.Collection; import java.util.Collections; public abstract class AbstractClassTypeConstructor extends AbstractTypeConstructor implements TypeConstructor { - private boolean hashCodeComputed; - private int hashCode; + private int hashCode = 0; public AbstractClassTypeConstructor(@NotNull StorageManager storageManager) { super(storageManager); @@ -39,17 +38,18 @@ public abstract class AbstractClassTypeConstructor extends AbstractTypeConstruct @Override public final int hashCode() { - if (!hashCodeComputed) { - hashCodeComputed = true; - ClassifierDescriptor descriptor = getDeclarationDescriptor(); - if (descriptor instanceof ClassDescriptor && hasMeaningfulFqName(descriptor)) { - hashCode = DescriptorUtils.getFqName(descriptor).hashCode(); - } - else { - hashCode = System.identityHashCode(this); - } + int currentHashCode = hashCode; + if (currentHashCode != 0) return currentHashCode; + + ClassifierDescriptor descriptor = getDeclarationDescriptor(); + if (descriptor instanceof ClassDescriptor && hasMeaningfulFqName(descriptor)) { + currentHashCode = DescriptorUtils.getFqName(descriptor).hashCode(); } - return hashCode; + else { + currentHashCode = System.identityHashCode(this); + } + hashCode = currentHashCode; + return currentHashCode; } @NotNull diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/checker/TypeCheckingProcedure.java b/core/descriptors/src/org/jetbrains/kotlin/types/checker/TypeCheckingProcedure.java index c886c9bfda0..a4770179f9e 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/checker/TypeCheckingProcedure.java +++ b/core/descriptors/src/org/jetbrains/kotlin/types/checker/TypeCheckingProcedure.java @@ -220,7 +220,9 @@ public class TypeCheckingProcedure { private boolean checkSubtypeForTheSameConstructor(@NotNull KotlinType subtype, @NotNull KotlinType supertype) { TypeConstructor constructor = subtype.getConstructor(); - assert constraints.assertEqualTypeConstructors(constructor, supertype.getConstructor()) : constructor + " is not " + supertype.getConstructor(); + + // this assert was moved to checker/utils.kt + //assert constraints.assertEqualTypeConstructors(constructor, supertype.getConstructor()) : constructor + " is not " + supertype.getConstructor(); List subArguments = subtype.getArguments(); List superArguments = supertype.getArguments(); diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/checker/utils.kt b/core/descriptors/src/org/jetbrains/kotlin/types/checker/utils.kt index 1a2c2ec3688..cd9a2c8e613 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/checker/utils.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/checker/utils.kt @@ -16,12 +16,10 @@ package org.jetbrains.kotlin.types.checker +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.renderer.DescriptorRenderer import org.jetbrains.kotlin.resolve.calls.inference.wrapWithCapturingSubstitution -import org.jetbrains.kotlin.types.KotlinType -import org.jetbrains.kotlin.types.TypeConstructorSubstitution -import org.jetbrains.kotlin.types.TypeUtils -import org.jetbrains.kotlin.types.Variance +import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.typesApproximation.approximateCapturedTypes import java.util.* @@ -66,11 +64,12 @@ fun findCorrespondingSupertype( currentPathNode = currentPathNode.previous } - if (!typeCheckingProcedureCallbacks.assertEqualTypeConstructors(substituted.constructor, supertypeConstructor)) { - throw AssertionError("Type constructors should be equals!" + - "substitutedSuperType: ${DescriptorRenderer.FQ_NAMES_IN_TYPES.renderType(substituted)}, " + - "foundSupertype: ${DescriptorRenderer.FQ_NAMES_IN_TYPES.renderType(currentSubtype)}, " + - "supertype: ${DescriptorRenderer.FQ_NAMES_IN_TYPES.renderType(supertype)}") + val substitutedConstructor = substituted.constructor + if (!typeCheckingProcedureCallbacks.assertEqualTypeConstructors(substitutedConstructor, supertypeConstructor)) { + throw AssertionError("Type constructors should be equals!\n" + + "substitutedSuperType: ${substitutedConstructor.debugInfo()}, \n\n" + + "supertype: ${supertypeConstructor.debugInfo()} \n" + + typeCheckingProcedureCallbacks.assertEqualTypeConstructors(substitutedConstructor, supertypeConstructor)) } return TypeUtils.makeNullableAsSpecified(substituted, isAnyMarkedNullable) @@ -85,3 +84,19 @@ fun findCorrespondingSupertype( } private fun KotlinType.approximate() = approximateCapturedTypes(this).upper + +private fun TypeConstructor.debugInfo() = buildString { + operator fun String.unaryPlus() = appendln(this) + + + "type: ${this@debugInfo}" + + "hashCode: ${this@debugInfo.hashCode()}" + + "javaClass: ${this@debugInfo.javaClass.canonicalName}" + var declarationDescriptor: DeclarationDescriptor? = declarationDescriptor + while (declarationDescriptor != null) { + + + "fqName: ${DescriptorRenderer.FQ_NAMES_IN_TYPES.render(declarationDescriptor)}" + + "javaClass: ${declarationDescriptor.javaClass.canonicalName}" + + declarationDescriptor = declarationDescriptor.containingDeclaration + } +} \ No newline at end of file