diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/OverloadChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/OverloadChecker.kt index 5eefdf8e03b..2c758e2ce92 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/OverloadChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/OverloadChecker.kt @@ -18,15 +18,11 @@ package org.jetbrains.kotlin.resolve import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilderImpl -import org.jetbrains.kotlin.resolve.calls.results.FlatSignature -import org.jetbrains.kotlin.resolve.calls.results.SpecificityComparisonCallbacks -import org.jetbrains.kotlin.resolve.calls.results.TypeSpecificityComparator -import org.jetbrains.kotlin.resolve.calls.results.isSignatureNotLessSpecific +import org.jetbrains.kotlin.resolve.calls.results.* import org.jetbrains.kotlin.resolve.descriptorUtil.hasLowPriorityInOverloadResolution import org.jetbrains.kotlin.resolve.descriptorUtil.isExtensionProperty import org.jetbrains.kotlin.resolve.descriptorUtil.varargParameterPosition import org.jetbrains.kotlin.types.ErrorUtils -import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.model.KotlinTypeMarker object OverloadabilitySpecificityCallbacks : SpecificityComparisonCallbacks { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/ShadowedExtensionChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/ShadowedExtensionChecker.kt index d56341f190b..e6b829f9e68 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/ShadowedExtensionChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/ShadowedExtensionChecker.kt @@ -22,9 +22,7 @@ import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilderImpl -import org.jetbrains.kotlin.resolve.calls.results.FlatSignature -import org.jetbrains.kotlin.resolve.calls.results.TypeSpecificityComparator -import org.jetbrains.kotlin.resolve.calls.results.isSignatureNotLessSpecific +import org.jetbrains.kotlin.resolve.calls.results.* import org.jetbrains.kotlin.resolve.descriptorUtil.hasHidesMembersAnnotation import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension import org.jetbrains.kotlin.resolve.descriptorUtil.varargParameterPosition @@ -137,4 +135,4 @@ class ShadowedExtensionChecker(val typeSpecificityComparator: TypeSpecificityCom } } -} \ No newline at end of file +} diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemBuilderImpl.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemBuilderImpl.kt index 154fc6d8b9f..2125028b561 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemBuilderImpl.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemBuilderImpl.kt @@ -18,7 +18,6 @@ package org.jetbrains.kotlin.resolve.calls.inference import org.jetbrains.kotlin.builtins.createFunctionType import org.jetbrains.kotlin.builtins.isBuiltinExtensionFunctionalType -import org.jetbrains.kotlin.builtins.isExtensionFunctionType import org.jetbrains.kotlin.builtins.isSuspendFunctionType import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor import org.jetbrains.kotlin.descriptors.annotations.Annotations diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/results/FlatSignatureForResolvedCall.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/results/FlatSignatureForResolvedCall.kt index 0507312c018..ecbe0c273f6 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/results/FlatSignatureForResolvedCall.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/results/FlatSignatureForResolvedCall.kt @@ -25,7 +25,6 @@ import org.jetbrains.kotlin.resolve.calls.model.DefaultValueArgument import org.jetbrains.kotlin.resolve.calls.model.MutableResolvedCall import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCallImpl -import org.jetbrains.kotlin.resolve.calls.results.FlatSignature.Companion.argumentValueType import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner import org.jetbrains.kotlin.util.CancellationChecker diff --git a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/results/FlatSignature.kt b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/results/FlatSignature.kt new file mode 100644 index 00000000000..d1390f464d3 --- /dev/null +++ b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/results/FlatSignature.kt @@ -0,0 +1,85 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.resolve.calls.results + +import org.jetbrains.kotlin.types.AbstractTypeChecker +import org.jetbrains.kotlin.types.model.* + +interface SpecificityComparisonCallbacks { + fun isNonSubtypeNotLessSpecific(specific: KotlinTypeMarker, general: KotlinTypeMarker): Boolean +} + +class FlatSignature constructor( + val origin: T, + val typeParameters: Collection, + val valueParameterTypes: List, + val hasExtensionReceiver: Boolean, + val hasVarargs: Boolean, + val numDefaults: Int, + val isExpect: Boolean, + val isSyntheticMember: Boolean +) { + val isGeneric = typeParameters.isNotEmpty() + + companion object +} + + +interface SimpleConstraintSystem { + fun registerTypeVariables(typeParameters: Collection): TypeSubstitutorMarker + fun addSubtypeConstraint(subType: KotlinTypeMarker, superType: KotlinTypeMarker) + fun hasContradiction(): Boolean + + // todo hack for migration + val captureFromArgument get() = false + + val context: TypeSystemInferenceExtensionContext +} + +fun SimpleConstraintSystem.isSignatureNotLessSpecific( + specific: FlatSignature, + general: FlatSignature, + callbacks: SpecificityComparisonCallbacks, + specificityComparator: TypeSpecificityComparator +): Boolean { + if (specific.hasExtensionReceiver != general.hasExtensionReceiver) return false + 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 + + if (specificityComparator.isDefinitelyLessSpecific(specificType, generalType)) { + return false + } + + if (typeParameters.isEmpty() || !generalType.dependsOnTypeParameters(context, typeParameters)) { + if (!AbstractTypeChecker.isSubtypeOf(context, specificType, generalType)) { + if (!callbacks.isNonSubtypeNotLessSpecific(specificType, generalType)) { + return false + } + } + } else { + val substitutedGeneralType = typeSubstitutor.safeSubstitute(context, generalType) + + /** + * Example: + * fun Array.sort(): Unit {} + * fun > Array.sort(): Unit {} + * 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 = + context.prepareType(specificType).let { if (captureFromArgument) context.captureFromExpression(it) ?: it else it } + addSubtypeConstraint(specificCapturedType, substitutedGeneralType) + } + } + + return !hasContradiction() +} + diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/CallableReferenceResolver.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/CallableReferenceResolver.kt index addd31a63a5..137a74466a0 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/CallableReferenceResolver.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/CallableReferenceResolver.kt @@ -24,10 +24,7 @@ import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemOperation import org.jetbrains.kotlin.resolve.calls.inference.components.ConstraintInjector import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutor import org.jetbrains.kotlin.resolve.calls.model.* -import org.jetbrains.kotlin.resolve.calls.results.FlatSignature -import org.jetbrains.kotlin.resolve.calls.results.OverloadingConflictResolver -import org.jetbrains.kotlin.resolve.calls.results.PlatformOverloadsSpecificityComparator -import org.jetbrains.kotlin.resolve.calls.results.TypeSpecificityComparator +import org.jetbrains.kotlin.resolve.calls.results.* import org.jetbrains.kotlin.resolve.calls.tower.ImplicitScopeTower import org.jetbrains.kotlin.resolve.calls.tower.TowerResolver import org.jetbrains.kotlin.resolve.calls.tower.isInapplicable diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/NewOverloadingConflictResolver.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/NewOverloadingConflictResolver.kt index f58a421ed9b..db8f2b9d41d 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/NewOverloadingConflictResolver.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/NewOverloadingConflictResolver.kt @@ -22,10 +22,7 @@ import org.jetbrains.kotlin.resolve.calls.inference.components.ConstraintInjecto import org.jetbrains.kotlin.resolve.calls.model.KotlinCallArgument import org.jetbrains.kotlin.resolve.calls.model.KotlinResolutionCandidate import org.jetbrains.kotlin.resolve.calls.model.ResolvedCallArgument -import org.jetbrains.kotlin.resolve.calls.results.FlatSignature -import org.jetbrains.kotlin.resolve.calls.results.OverloadingConflictResolver -import org.jetbrains.kotlin.resolve.calls.results.PlatformOverloadsSpecificityComparator -import org.jetbrains.kotlin.resolve.calls.results.TypeSpecificityComparator +import org.jetbrains.kotlin.resolve.calls.results.* import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner import org.jetbrains.kotlin.util.CancellationChecker 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 deleted file mode 100644 index 31e5088fe1c..00000000000 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/results/FlatSignature.kt +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright 2010-2016 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.kotlin.resolve.calls.results - -import org.jetbrains.kotlin.builtins.getValueParameterTypesFromCallableReflectionType -import org.jetbrains.kotlin.descriptors.CallableDescriptor -import org.jetbrains.kotlin.descriptors.MemberDescriptor -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.AbstractTypeChecker -import org.jetbrains.kotlin.types.KotlinType -import org.jetbrains.kotlin.types.UnwrappedType -import org.jetbrains.kotlin.types.model.* - -interface SpecificityComparisonCallbacks { - fun isNonSubtypeNotLessSpecific(specific: KotlinTypeMarker, general: KotlinTypeMarker): Boolean -} - -class FlatSignature constructor( - val origin: T, - val typeParameters: Collection, - val valueParameterTypes: List, - val hasExtensionReceiver: Boolean, - val hasVarargs: Boolean, - val numDefaults: Int, - val isExpect: Boolean, - val isSyntheticMember: Boolean -) { - val isGeneric = typeParameters.isNotEmpty() - - companion object { - fun createFromReflectionType( - origin: T, - descriptor: CallableDescriptor, - numDefaults: Int, - // Reflection type for callable references with bound receiver doesn't contain receiver type - hasBoundExtensionReceiver: Boolean, - reflectionType: UnwrappedType - ): FlatSignature { - // Note that receiver is taking over descriptor, not reflection type - // This is correct as extension receiver can't have any defaults/varargs/coercions, so there is no need to use reflection type - // Plus, currently, receiver for reflection type is taking from *candidate*, see buildReflectionType, this candidate can - // have transient receiver which is not the same in its signature - val receiver = descriptor.extensionReceiverParameter?.type - val parameters = reflectionType.getValueParameterTypesFromCallableReflectionType( - receiver != null && !hasBoundExtensionReceiver - ).map { it.type } - - return FlatSignature( - origin, - descriptor.typeParameters, - listOfNotNull(receiver) + parameters, - hasExtensionReceiver = receiver != null, - hasVarargs = descriptor.valueParameters.any { it.varargElementType != null }, - numDefaults = numDefaults, - isExpect = descriptor is MemberDescriptor && descriptor.isExpect, - isSyntheticMember = descriptor is SyntheticMemberDescriptor<*> - ) - } - - fun create( - origin: T, - descriptor: CallableDescriptor, - numDefaults: Int, - parameterTypes: List - ): FlatSignature { - val extensionReceiverType = descriptor.extensionReceiverParameter?.type - - return FlatSignature( - origin, - descriptor.typeParameters, - valueParameterTypes = - listOfNotNull(extensionReceiverType) + parameterTypes, - hasExtensionReceiver = extensionReceiverType != null, - hasVarargs = descriptor.valueParameters.any { it.varargElementType != null }, - numDefaults = numDefaults, - isExpect = descriptor is MemberDescriptor && descriptor.isExpect, - isSyntheticMember = descriptor is SyntheticMemberDescriptor<*> - ) - } - - fun createFromCallableDescriptor( - descriptor: D - ): FlatSignature = - create(descriptor, descriptor, numDefaults = 0, parameterTypes = descriptor.valueParameters.map { it.argumentValueType }) - - fun createForPossiblyShadowedExtension(descriptor: D): FlatSignature = - FlatSignature( - descriptor, - descriptor.typeParameters, - valueParameterTypes = descriptor.valueParameters.map { it.argumentValueType }, - hasExtensionReceiver = false, - hasVarargs = descriptor.valueParameters.any { it.varargElementType != null }, - numDefaults = descriptor.valueParameters.count { it.hasDefaultValue() }, - isExpect = descriptor is MemberDescriptor && descriptor.isExpect, - isSyntheticMember = descriptor is SyntheticMemberDescriptor<*> - ) - - val ValueParameterDescriptor.argumentValueType get() = varargElementType ?: type - } -} - - -interface SimpleConstraintSystem { - fun registerTypeVariables(typeParameters: Collection): TypeSubstitutorMarker - fun addSubtypeConstraint(subType: KotlinTypeMarker, superType: KotlinTypeMarker) - fun hasContradiction(): Boolean - - // todo hack for migration - val captureFromArgument get() = false - - val context: TypeSystemInferenceExtensionContext -} - -fun SimpleConstraintSystem.isSignatureNotLessSpecific( - specific: FlatSignature, - general: FlatSignature, - callbacks: SpecificityComparisonCallbacks, - specificityComparator: TypeSpecificityComparator -): Boolean { - if (specific.hasExtensionReceiver != general.hasExtensionReceiver) return false - 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 - - if (specificityComparator.isDefinitelyLessSpecific(specificType, generalType)) { - return false - } - - if (typeParameters.isEmpty() || !generalType.dependsOnTypeParameters(context, typeParameters)) { - if (!AbstractTypeChecker.isSubtypeOf(context, specificType, generalType)) { - if (!callbacks.isNonSubtypeNotLessSpecific(specificType, generalType)) { - return false - } - } - } else { - val substitutedGeneralType = typeSubstitutor.safeSubstitute(context, generalType) - - /** - * Example: - * fun Array.sort(): Unit {} - * fun > Array.sort(): Unit {} - * 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 = - context.prepareType(specificType).let { if (captureFromArgument) context.captureFromExpression(it) ?: it else it } - addSubtypeConstraint(specificCapturedType, substitutedGeneralType) - } - } - - return !hasContradiction() -} - diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/results/FlatSignatureUtils.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/results/FlatSignatureUtils.kt new file mode 100644 index 00000000000..92abbfafea7 --- /dev/null +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/results/FlatSignatureUtils.kt @@ -0,0 +1,84 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.resolve.calls.results + +import org.jetbrains.kotlin.builtins.getValueParameterTypesFromCallableReflectionType +import org.jetbrains.kotlin.descriptors.CallableDescriptor +import org.jetbrains.kotlin.descriptors.MemberDescriptor +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.KotlinType +import org.jetbrains.kotlin.types.UnwrappedType + +fun FlatSignature.Companion.createFromReflectionType( + origin: T, + descriptor: CallableDescriptor, + numDefaults: Int, + // Reflection type for callable references with bound receiver doesn't contain receiver type + hasBoundExtensionReceiver: Boolean, + reflectionType: UnwrappedType +): FlatSignature { + // Note that receiver is taking over descriptor, not reflection type + // This is correct as extension receiver can't have any defaults/varargs/coercions, so there is no need to use reflection type + // Plus, currently, receiver for reflection type is taking from *candidate*, see buildReflectionType, this candidate can + // have transient receiver which is not the same in its signature + val receiver = descriptor.extensionReceiverParameter?.type + val parameters = reflectionType.getValueParameterTypesFromCallableReflectionType( + receiver != null && !hasBoundExtensionReceiver + ).map { it.type } + + return FlatSignature( + origin, + descriptor.typeParameters, + listOfNotNull(receiver) + parameters, + hasExtensionReceiver = receiver != null, + hasVarargs = descriptor.valueParameters.any { it.varargElementType != null }, + numDefaults = numDefaults, + isExpect = descriptor is MemberDescriptor && descriptor.isExpect, + isSyntheticMember = descriptor is SyntheticMemberDescriptor<*> + ) +} + +fun FlatSignature.Companion.create( + origin: T, + descriptor: CallableDescriptor, + numDefaults: Int, + parameterTypes: List +): FlatSignature { + val extensionReceiverType = descriptor.extensionReceiverParameter?.type + + return FlatSignature( + origin, + descriptor.typeParameters, + valueParameterTypes = + listOfNotNull(extensionReceiverType) + parameterTypes, + hasExtensionReceiver = extensionReceiverType != null, + hasVarargs = descriptor.valueParameters.any { it.varargElementType != null }, + numDefaults = numDefaults, + isExpect = descriptor is MemberDescriptor && descriptor.isExpect, + isSyntheticMember = descriptor is SyntheticMemberDescriptor<*> + ) +} + +fun FlatSignature.Companion.createFromCallableDescriptor( + descriptor: D +): FlatSignature = + create(descriptor, descriptor, numDefaults = 0, parameterTypes = descriptor.valueParameters.map { it.argumentValueType }) + +fun FlatSignature.Companion.createForPossiblyShadowedExtension(descriptor: D): FlatSignature = + FlatSignature( + descriptor, + descriptor.typeParameters, + valueParameterTypes = descriptor.valueParameters.map { it.argumentValueType }, + hasExtensionReceiver = false, + hasVarargs = descriptor.valueParameters.any { it.varargElementType != null }, + numDefaults = descriptor.valueParameters.count { it.hasDefaultValue() }, + isExpect = descriptor is MemberDescriptor && descriptor.isExpect, + isSyntheticMember = descriptor is SyntheticMemberDescriptor<*> + ) + +val ValueParameterDescriptor.argumentValueType get() = varargElementType ?: type