Don't approximate abbreviation during substitution it as it can't be projected at top-level

^KT-42036 Fixed
This commit is contained in:
Victor Petukhov
2020-12-29 14:21:08 +03:00
parent 009add2b41
commit 30a5eee481
17 changed files with 258 additions and 4 deletions
@@ -122,7 +122,7 @@ fun TypeSubstitution.wrapWithCapturingSubstitution(needApproximation: Boolean =
this.arguments.zip(this.parameters).map {
it.first.createCapturedIfNeeded(it.second)
}.toTypedArray(),
approximateCapturedTypes = needApproximation
approximateContravariantCapturedTypes = needApproximation
)
else
object : DelegatedTypeSubstitution(this@wrapWithCapturingSubstitution) {
@@ -88,7 +88,7 @@ abstract class TypeConstructorSubstitution : TypeSubstitution() {
class IndexedParametersSubstitution(
val parameters: Array<TypeParameterDescriptor>,
val arguments: Array<TypeProjection>,
private val approximateCapturedTypes: Boolean = false
private val approximateContravariantCapturedTypes: Boolean = false
) : TypeSubstitution() {
init {
assert(parameters.size <= arguments.size) {
@@ -103,7 +103,7 @@ class IndexedParametersSubstitution(
override fun isEmpty(): Boolean = arguments.isEmpty()
override fun approximateContravariantCapturedTypes() = approximateCapturedTypes
override fun approximateContravariantCapturedTypes() = approximateContravariantCapturedTypes
override fun get(key: KotlinType): TypeProjection? {
val parameter = key.constructor.declarationDescriptor as? TypeParameterDescriptor ?: return null
@@ -54,6 +54,19 @@ public class TypeSubstitutor implements TypeSubstitutorMarker {
return new TypeSubstitutor(substitution);
}
@NotNull
public TypeSubstitutor replaceWithNonApproximatingSubstitution() {
if (!(substitution instanceof IndexedParametersSubstitution) || !substitution.approximateContravariantCapturedTypes()) return this;
return new TypeSubstitutor(
new IndexedParametersSubstitution(
((IndexedParametersSubstitution) substitution).getParameters(),
((IndexedParametersSubstitution) substitution).getArguments(),
false
)
);
}
@NotNull
public static TypeSubstitutor createChainedSubstitutor(@NotNull TypeSubstitution first, @NotNull TypeSubstitution second) {
return create(DisjointKeysUnionTypeSubstitution.create(first, second));
@@ -302,7 +315,9 @@ public class TypeSubstitutor implements TypeSubstitutorMarker {
KotlinType substitutedAbbreviation = null;
SimpleType abbreviation = SpecialTypesKt.getAbbreviation(type);
if (abbreviation != null) {
substitutedAbbreviation = substitute(abbreviation, Variance.INVARIANT);
// We shouldn't approximate abbreviation at the top-level as they can't be projected: below we substitute this always as invariant
TypeSubstitutor substitutorForAbbreviation = replaceWithNonApproximatingSubstitution();
substitutedAbbreviation = substitutorForAbbreviation.substitute(abbreviation, Variance.INVARIANT);
}
List<TypeProjection> substitutedArguments = substituteTypeArguments(