From daed74f9b20827e0fc3c4d70b0cd4f8dab72db77 Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Fri, 6 Nov 2015 12:06:01 +0300 Subject: [PATCH] Fix supertypes consistency check See testKt5508: `inner class B : A>()` is effectively the same as `A.B : A.B>` or `B : A>`. The latter is because we add outer class parameters to inner type constructor. The problem is that we treat type constructors of first TP of 'A' and of second type parameter (copy) of 'B' just the same and report INCONSISTENT_TYPE_PARAMETER_VALUES. So we supposse it's more correct to compare type parameter descriptors instead --- .../kotlinSignature/SignaturesPropagationData.java | 4 ++-- .../kotlin/resolve/DeclarationsChecker.java | 9 +++------ .../jetbrains/kotlin/types/SubstitutionUtils.java | 14 +++++++------- 3 files changed, 12 insertions(+), 15 deletions(-) diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/kotlinSignature/SignaturesPropagationData.java b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/kotlinSignature/SignaturesPropagationData.java index a46a4f9f719..7d3ba4e211b 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/kotlinSignature/SignaturesPropagationData.java +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/kotlinSignature/SignaturesPropagationData.java @@ -526,7 +526,7 @@ public class SignaturesPropagationData { // #1 of Baz -> A // #0 of Foo -> A (mapped to itself) // #1 of Foo -> B (mapped to itself) - Multimap substitution = SubstitutionUtils.buildDeepSubstitutionMultimap( + Multimap substitution = SubstitutionUtils.buildDeepSubstitutionMultimap( TypeUtils.makeUnsubstitutedType(klass, ErrorUtils.createErrorScope("Do not access this scope", true))); // for each parameter of klass, hold arguments in corresponding supertypes @@ -547,7 +547,7 @@ public class SignaturesPropagationData { // 4. typeFromSuper = Baz, parameter = "#1 of Baz", argument = CharSequence // if it is mapped to klass' parameter, then store it into map - for (TypeProjection projection : substitution.get(parameter.getTypeConstructor())) { + for (TypeProjection projection : substitution.get(parameter)) { // 1. projection = A // 2. projection = List // 3. projection = Boolean diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.java index bfa725014f2..8cb5f10ae9d 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DeclarationsChecker.java @@ -202,15 +202,12 @@ public class DeclarationsChecker { @NotNull ClassifierDescriptor classifierDescriptor, @NotNull PsiElement sourceElement ) { - Multimap multimap = + Multimap multimap = SubstitutionUtils.buildDeepSubstitutionMultimap(classifierDescriptor.getDefaultType()); - for (Map.Entry> entry : multimap.asMap().entrySet()) { + for (Map.Entry> entry : multimap.asMap().entrySet()) { Collection projections = entry.getValue(); if (projections.size() > 1) { - TypeConstructor typeConstructor = entry.getKey(); - DeclarationDescriptor declarationDescriptor = typeConstructor.getDeclarationDescriptor(); - assert declarationDescriptor instanceof TypeParameterDescriptor : declarationDescriptor; - TypeParameterDescriptor typeParameterDescriptor = (TypeParameterDescriptor) declarationDescriptor; + TypeParameterDescriptor typeParameterDescriptor = entry.getKey(); // Immediate arguments of supertypes cannot be projected Set conflictingTypes = Sets.newLinkedHashSet(); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/SubstitutionUtils.java b/compiler/frontend/src/org/jetbrains/kotlin/types/SubstitutionUtils.java index 63b704f9f64..50ff55c0057 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/SubstitutionUtils.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/SubstitutionUtils.java @@ -21,8 +21,8 @@ import com.google.common.collect.Maps; import com.google.common.collect.Multimap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor; import org.jetbrains.kotlin.builtins.KotlinBuiltIns; +import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor; import java.util.List; import java.util.Map; @@ -57,8 +57,8 @@ public class SubstitutionUtils { F declared in MyFooCollection -> out CharSequence */ @NotNull - public static Multimap buildDeepSubstitutionMultimap(@NotNull KotlinType type) { - Multimap fullSubstitution = LinkedHashMultimap.create(); + public static Multimap buildDeepSubstitutionMultimap(@NotNull KotlinType type) { + Multimap fullSubstitution = LinkedHashMultimap.create(); Map substitution = Maps.newHashMap(); TypeSubstitutor typeSubstitutor = TypeSubstitutor.create(substitution); // we use the mutability of the map here @@ -71,7 +71,7 @@ public class SubstitutionUtils { @NotNull KotlinType context, @NotNull TypeSubstitutor substitutor, @NotNull Map substitution, - @Nullable Multimap fullSubstitution + @Nullable Multimap typeParameterMapping ) { List parameters = context.getConstructor().getParameters(); List arguments = context.getArguments(); @@ -87,13 +87,13 @@ public class SubstitutionUtils { TypeProjection substitute = substitutor.substitute(argument); assert substitute != null; substitution.put(parameter.getTypeConstructor(), substitute); - if (fullSubstitution != null) { - fullSubstitution.put(parameter.getTypeConstructor(), substitute); + if (typeParameterMapping != null) { + typeParameterMapping.put(parameter, substitute); } } if (KotlinBuiltIns.isNothingOrNullableNothing(context)) return; for (KotlinType supertype : context.getConstructor().getSupertypes()) { - fillInDeepSubstitutor(supertype, substitutor, substitution, fullSubstitution); + fillInDeepSubstitutor(supertype, substitutor, substitution, typeParameterMapping); } } }