diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ClassicTypeSystemContextForCS.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ClassicTypeSystemContextForCS.kt index 2fd8d5f489c..df4b05c2ca3 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ClassicTypeSystemContextForCS.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ClassicTypeSystemContextForCS.kt @@ -11,10 +11,7 @@ import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstituto import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutorByConstructorMap import org.jetbrains.kotlin.resolve.calls.inference.model.NewConstraintSystemImpl import org.jetbrains.kotlin.resolve.calls.inference.model.NewTypeVariable -import org.jetbrains.kotlin.types.StubType -import org.jetbrains.kotlin.types.TypeConstructor -import org.jetbrains.kotlin.types.TypeProjectionImpl -import org.jetbrains.kotlin.types.UnwrappedType +import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.checker.ClassicTypeSystemContext import org.jetbrains.kotlin.types.checker.NewCapturedType import org.jetbrains.kotlin.types.checker.NewCapturedTypeConstructor @@ -61,9 +58,12 @@ class ClassicTypeSystemContextForCS(override val builtIns: KotlinBuiltIns) : Typ } override fun TypeSubstitutorMarker.safeSubstitute(type: KotlinTypeMarker): KotlinTypeMarker { - require(type is UnwrappedType, this::errorMessage) - require(this is NewTypeSubstitutor, this::errorMessage) - return this.safeSubstitute(type) + require(type is UnwrappedType, type::errorMessage) + return when (this) { + is NewTypeSubstitutor -> safeSubstitute(type) + is TypeSubstitutor -> safeSubstitute(type, Variance.INVARIANT) + else -> error(this.errorMessage()) + } } override fun createStubType(typeVariable: TypeVariableMarker): StubTypeMarker { diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/SimpleConstraintSystemImpl.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/SimpleConstraintSystemImpl.kt index 05da08a5a43..db34d9def96 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/SimpleConstraintSystemImpl.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/SimpleConstraintSystemImpl.kt @@ -26,10 +26,9 @@ import org.jetbrains.kotlin.resolve.calls.inference.substitute import org.jetbrains.kotlin.resolve.calls.results.SimpleConstraintSystem import org.jetbrains.kotlin.types.TypeConstructorSubstitution import org.jetbrains.kotlin.types.checker.requireOrDescribe -import org.jetbrains.kotlin.types.TypeSubstitutor -import org.jetbrains.kotlin.types.UnwrappedType import org.jetbrains.kotlin.types.model.KotlinTypeMarker import org.jetbrains.kotlin.types.model.TypeParameterMarker +import org.jetbrains.kotlin.types.model.TypeSubstitutorMarker import org.jetbrains.kotlin.types.model.TypeSystemInferenceExtensionContext import org.jetbrains.kotlin.types.typeUtil.asTypeProjection @@ -38,7 +37,7 @@ class SimpleConstraintSystemImpl(constraintInjector: ConstraintInjector, builtIn val csBuilder: ConstraintSystemBuilder = system.getBuilder() - override fun registerTypeVariables(typeParameters: Collection): TypeSubstitutor { + override fun registerTypeVariables(typeParameters: Collection): TypeSubstitutorMarker { val substitutionMap = typeParameters.associate { requireOrDescribe(it is TypeParameterDescriptor, it) @@ -58,8 +57,6 @@ class SimpleConstraintSystemImpl(constraintInjector: ConstraintInjector, builtIn } override fun addSubtypeConstraint(subType: KotlinTypeMarker, superType: KotlinTypeMarker) { - require(subType is UnwrappedType) - require(superType is UnwrappedType) csBuilder.addSubtypeConstraint( subType, superType, diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/results/FlatSignature.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/results/FlatSignature.kt index c6f7276d24e..1e4b9ef62da 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/results/FlatSignature.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/results/FlatSignature.kt @@ -22,10 +22,7 @@ import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor import org.jetbrains.kotlin.descriptors.synthetic.SyntheticMemberDescriptor import org.jetbrains.kotlin.resolve.calls.components.hasDefaultValue import org.jetbrains.kotlin.types.* -import org.jetbrains.kotlin.types.checker.captureFromExpression -import org.jetbrains.kotlin.types.model.KotlinTypeMarker -import org.jetbrains.kotlin.types.model.TypeParameterMarker -import org.jetbrains.kotlin.types.model.TypeSystemInferenceExtensionContext +import org.jetbrains.kotlin.types.model.* interface SpecificityComparisonCallbacks { fun isNonSubtypeNotLessSpecific(specific: KotlinTypeMarker, general: KotlinTypeMarker): Boolean @@ -114,7 +111,7 @@ class FlatSignature constructor( interface SimpleConstraintSystem { - fun registerTypeVariables(typeParameters: Collection): TypeSubstitutor + fun registerTypeVariables(typeParameters: Collection): TypeSubstitutorMarker fun addSubtypeConstraint(subType: KotlinTypeMarker, superType: KotlinTypeMarker) fun hasContradiction(): Boolean @@ -134,6 +131,7 @@ fun SimpleConstraintSystem.isSignatureNotLessSpecific( if (specific.valueParameterTypes.size != general.valueParameterTypes.size) return false val typeParameters = general.typeParameters + val typeSubstitutor = registerTypeVariables(typeParameters) for ((specificType, generalType) in specific.valueParameterTypes.zip(general.valueParameterTypes)) { if (specificType == null || generalType == null) continue @@ -142,18 +140,14 @@ fun SimpleConstraintSystem.isSignatureNotLessSpecific( return false } - if (typeParameters.isEmpty() /*|| !TypeUtils.dependsOnTypeParameters(generalType, typeParameters)*/) { + if (typeParameters.isEmpty() || !generalType.dependsOnTypeParameters(context, typeParameters)) { if (!AbstractTypeChecker.isSubtypeOf(context, specificType, generalType)) { if (!callbacks.isNonSubtypeNotLessSpecific(specificType, generalType)) { return false } } } else { - val typeSubstitutor = registerTypeVariables(typeParameters) - require(generalType is KotlinType) { TODO("not supported") } - require(specificType is KotlinType) { TODO("not supported") } - - val substitutedGeneralType = typeSubstitutor.safeSubstitute(generalType, Variance.INVARIANT) + val substitutedGeneralType = typeSubstitutor.safeSubstitute(context, generalType) /** * Example: @@ -162,8 +156,9 @@ fun SimpleConstraintSystem.isSignatureNotLessSpecific( * Here, when we try solve this CS(Y is variables) then Array <: Array and this system impossible to solve, * so we capture types from receiver and value parameters. */ - val specificCapturedType = specificType.unwrap().let { if (captureFromArgument) captureFromExpression(it) ?: it else it } - addSubtypeConstraint(specificCapturedType, substitutedGeneralType.unwrap()) + val specificCapturedType = + context.prepareType(specificType).let { if (captureFromArgument) context.captureFromExpression(it) ?: it else it } + addSubtypeConstraint(specificCapturedType, substitutedGeneralType) } } diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/TypeSubstitutor.java b/core/descriptors/src/org/jetbrains/kotlin/types/TypeSubstitutor.java index 893a87c20cf..af389bed94e 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/TypeSubstitutor.java +++ b/core/descriptors/src/org/jetbrains/kotlin/types/TypeSubstitutor.java @@ -26,6 +26,7 @@ import org.jetbrains.kotlin.descriptors.annotations.CompositeAnnotations; import org.jetbrains.kotlin.descriptors.annotations.FilteredAnnotations; import org.jetbrains.kotlin.name.FqName; import org.jetbrains.kotlin.resolve.calls.inference.CapturedTypeConstructorKt; +import org.jetbrains.kotlin.types.model.TypeSubstitutorMarker; import org.jetbrains.kotlin.types.typeUtil.TypeUtilsKt; import org.jetbrains.kotlin.types.typesApproximation.CapturedTypeApproximationKt; import org.jetbrains.kotlin.utils.ExceptionUtilsKt; @@ -34,7 +35,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; -public class TypeSubstitutor { +public class TypeSubstitutor implements TypeSubstitutorMarker { private static final int MAX_RECURSION_DEPTH = 100; diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/checker/ClassicTypeSystemContext.kt b/core/descriptors/src/org/jetbrains/kotlin/types/checker/ClassicTypeSystemContext.kt index 3341a6187d0..4e3723df460 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/checker/ClassicTypeSystemContext.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/checker/ClassicTypeSystemContext.kt @@ -444,7 +444,9 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext { } override fun TypeSubstitutorMarker.safeSubstitute(type: KotlinTypeMarker): KotlinTypeMarker { - errorSupportedOnlyInTypeInference() + require(type is UnwrappedType, type::errorMessage) + require(this is TypeSubstitutor, this::errorMessage) + return safeSubstitute(type, Variance.INVARIANT) } override fun TypeVariableMarker.defaultType(): SimpleTypeMarker { @@ -470,8 +472,14 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext { require(this is KotlinType, this::errorMessage) return KotlinBuiltIns.isPrimitiveType(this) } + + override fun captureFromExpression(type: KotlinTypeMarker): KotlinTypeMarker? { + return captureFromExpressionInternal(type as UnwrappedType) + } } +private fun captureFromExpressionInternal(type: UnwrappedType) = captureFromExpression(type) + private fun hasNoInferInternal(type: UnwrappedType): Boolean { return type.hasNoInferAnnotation() } diff --git a/core/type-system/src/org/jetbrains/kotlin/types/model/MarkerExtensions.kt b/core/type-system/src/org/jetbrains/kotlin/types/model/MarkerExtensions.kt index ab06558c2bd..6868655572b 100644 --- a/core/type-system/src/org/jetbrains/kotlin/types/model/MarkerExtensions.kt +++ b/core/type-system/src/org/jetbrains/kotlin/types/model/MarkerExtensions.kt @@ -11,4 +11,15 @@ fun TypeSubstitutorMarker.safeSubstitute( type: KotlinTypeMarker ) = with(c) { safeSubstitute(type) } -fun TypeVariableMarker.defaultType(c: TypeSystemInferenceExtensionContext) = with(c) { defaultType() } \ No newline at end of file +fun TypeVariableMarker.defaultType(c: TypeSystemInferenceExtensionContext) = with(c) { defaultType() } + +fun KotlinTypeMarker.dependsOnTypeConstructor(c: TypeSystemInferenceExtensionContext, typeConstructors: Set) = + with(c) { + contains { it.typeConstructor() in typeConstructors } + } + +fun KotlinTypeMarker.dependsOnTypeParameters(c: TypeSystemInferenceExtensionContext, typeParameters: Collection) = + with(c) { + val typeConstructors = typeParameters.mapTo(mutableSetOf()) { it.getTypeConstructor() } + dependsOnTypeConstructor(c, typeConstructors) + } \ No newline at end of file diff --git a/core/type-system/src/org/jetbrains/kotlin/types/model/TypeSystemContext.kt b/core/type-system/src/org/jetbrains/kotlin/types/model/TypeSystemContext.kt index 9475d4e4740..ef4a57de9a4 100644 --- a/core/type-system/src/org/jetbrains/kotlin/types/model/TypeSystemContext.kt +++ b/core/type-system/src/org/jetbrains/kotlin/types/model/TypeSystemContext.kt @@ -223,6 +223,8 @@ interface TypeSystemContext : TypeSystemOptimizationContext { status: CaptureStatus ): SimpleTypeMarker? + fun captureFromExpression(type: KotlinTypeMarker): KotlinTypeMarker? + fun SimpleTypeMarker.asArgumentList(): TypeArgumentListMarker operator fun TypeArgumentListMarker.get(index: Int): TypeArgumentMarker {