diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/OverloadChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/OverloadChecker.kt index c3b26bdd288..ef3a1c65909 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/OverloadChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/OverloadChecker.kt @@ -22,6 +22,7 @@ import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.name.FqNameUnsafe import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.calls.results.* +import org.jetbrains.kotlin.resolve.calls.tower.getTypeAliasConstructors import org.jetbrains.kotlin.resolve.descriptorUtil.hasLowPriorityInOverloadResolution import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.types.ErrorUtils @@ -99,14 +100,25 @@ class OverloadChecker(val specificityComparator: TypeSpecificityComparator) { ): MultiMap { val packageMembersByName = MultiMap() - collectModulePackageMembersWithSameName(packageMembersByName, c.functions.values + c.declaredClasses.values, overloadFilter) { + collectModulePackageMembersWithSameName( + packageMembersByName, + c.functions.values + c.declaredClasses.values + c.typeAliases.values, + overloadFilter + ) { scope, name -> val functions = scope.getContributedFunctions(name, NoLookupLocation.WHEN_CHECK_REDECLARATIONS) val classifier = scope.getContributedClassifier(name, NoLookupLocation.WHEN_CHECK_REDECLARATIONS) - if (classifier is ClassDescriptor && !classifier.kind.isSingleton) - functions + classifier.constructors - else - functions + when (classifier) { + is ClassDescriptor -> + if (!classifier.kind.isSingleton) + functions + classifier.constructors + else + functions + is TypeAliasDescriptor -> + functions + classifier.getTypeAliasConstructors() + else -> + functions + } } collectModulePackageMembersWithSameName(packageMembersByName, c.properties.values, overloadFilter) { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/OverloadResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/OverloadResolver.kt index 5b4f1275958..26171b79968 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/OverloadResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/OverloadResolver.kt @@ -18,10 +18,12 @@ package org.jetbrains.kotlin.resolve import com.intellij.util.containers.MultiMap import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.idea.MainFunctionDetector import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.KtDeclaration +import org.jetbrains.kotlin.resolve.calls.tower.getTypeAliasConstructors import org.jetbrains.kotlin.utils.addToStdlib.check class OverloadResolver( @@ -31,7 +33,7 @@ class OverloadResolver( ) { fun checkOverloads(c: BodiesResolveContext) { - val inClasses = findConstructorsInNestedClasses(c) + val inClasses = findConstructorsInNestedClassesAndTypeAliases(c) for (entry in c.declaredClasses.entries) { checkOverloadsInClass(entry.value, inClasses.get(entry.value)) @@ -39,8 +41,8 @@ class OverloadResolver( checkOverloadsInPackages(c) } - private fun findConstructorsInNestedClasses(c: BodiesResolveContext): MultiMap { - val constructorsInNestedClasses = MultiMap.create() + private fun findConstructorsInNestedClassesAndTypeAliases(c: BodiesResolveContext): MultiMap { + val constructorsByOuterClass = MultiMap.create() for (klass in c.declaredClasses.values) { if (klass.kind.isSingleton || klass.name.isSpecial) { @@ -52,7 +54,7 @@ class OverloadResolver( // TODO: check overload conflicts of functions with constructors in scripts } else if (containingDeclaration is ClassDescriptor) { - constructorsInNestedClasses.putValues(containingDeclaration, klass.constructors) + constructorsByOuterClass.putValues(containingDeclaration, klass.constructors) } else if (!(containingDeclaration is FunctionDescriptor || containingDeclaration is PropertyDescriptor || @@ -61,7 +63,14 @@ class OverloadResolver( } } - return constructorsInNestedClasses + for (typeAlias in c.typeAliases.values) { + val containingDeclaration = typeAlias.containingDeclaration + if (containingDeclaration is ClassDescriptor) { + constructorsByOuterClass.putValues(containingDeclaration, typeAlias.getTypeAliasConstructors()) + } + } + + return constructorsByOuterClass } private fun checkOverloadsInPackages(c: BodiesResolveContext) { @@ -82,8 +91,14 @@ class OverloadResolver( functionsByName.putValue(function.name, function) } - for (nestedClassConstructor in nestedClassConstructors) { - functionsByName.putValue(nestedClassConstructor.containingDeclaration.name, nestedClassConstructor) + for (nestedConstructor in nestedClassConstructors) { + val name = + if (nestedConstructor is TypeAliasConstructorDescriptor) + nestedConstructor.typeAliasDescriptor.name + else + nestedConstructor.containingDeclaration.name + + functionsByName.putValue(name, nestedConstructor) } for (e in functionsByName.entrySet()) { diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/TowerLevels.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/TowerLevels.kt index 1bcddab626d..50acfa3ce15 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/TowerLevels.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/tower/TowerLevels.kt @@ -244,7 +244,7 @@ private fun ResolutionScope.getContributedFunctionsAndConstructors(name: Name, l val classifier = getContributedClassifier(name, location) return getContributedFunctions(name, location) + (getClassWithConstructors(classifier)?.constructors?.filter { it.dispatchReceiverParameter == null } ?: emptyList()) + - (classifier?.getTypeAliasConstructors(false) ?: emptyList()) + (classifier?.getTypeAliasConstructors() ?: emptyList()) } private fun ResolutionScope.getContributedVariablesAndObjects(name: Name, location: LookupLocation): Collection { @@ -274,7 +274,7 @@ private fun getClassWithConstructors(classifier: ClassifierDescriptor?): ClassDe private val ClassDescriptor.canHaveCallableConstructors: Boolean get() = !ErrorUtils.isError(this) && !kind.isSingleton -private fun ClassifierDescriptor.getTypeAliasConstructors(inner: Boolean): Collection { +fun ClassifierDescriptor.getTypeAliasConstructors(): Collection { if (this !is TypeAliasDescriptor) return emptyList() val classDescriptor = this.classDescriptor ?: return emptyList() @@ -282,10 +282,11 @@ private fun ClassifierDescriptor.getTypeAliasConstructors(inner: Boolean): Colle val substitutor = this.getTypeSubstitutorForUnderlyingClass() ?: throw AssertionError("classDescriptor should be non-null for $this") - return classDescriptor.constructors.filter { - if (inner) it.dispatchReceiverParameter != null else it.dispatchReceiverParameter == null - }.mapNotNull { - TypeAliasConstructorDescriptorImpl.create(this, it, substitutor) + return classDescriptor.constructors.mapNotNull { + if (it.dispatchReceiverParameter == null) + TypeAliasConstructorDescriptorImpl.create(this, it, substitutor) + else + null } } diff --git a/compiler/testData/diagnostics/tests/redeclarations/TypeAliasCtorVsFun.kt b/compiler/testData/diagnostics/tests/redeclarations/TypeAliasCtorVsFun.kt new file mode 100644 index 00000000000..0dbe690a9b7 --- /dev/null +++ b/compiler/testData/diagnostics/tests/redeclarations/TypeAliasCtorVsFun.kt @@ -0,0 +1,13 @@ +class C(val x: Int) + +typealias CC = C + +fun CC(x: Int) = x + +class Outer { + class C(val x: Int) + + typealias CC = C + + fun CC(x: Int) = x +} diff --git a/compiler/testData/diagnostics/tests/redeclarations/TypeAliasCtorVsFun.txt b/compiler/testData/diagnostics/tests/redeclarations/TypeAliasCtorVsFun.txt new file mode 100644 index 00000000000..44ce22b14ef --- /dev/null +++ b/compiler/testData/diagnostics/tests/redeclarations/TypeAliasCtorVsFun.txt @@ -0,0 +1,29 @@ +package + +public typealias CC = C +public fun CC(/*0*/ x: kotlin.Int): kotlin.Int + +public final class C { + public constructor C(/*0*/ x: kotlin.Int) + public final val x: kotlin.Int + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class Outer { + public typealias CC = Outer.C + public constructor Outer() + public final fun CC(/*0*/ x: kotlin.Int): kotlin.Int + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + public final class C { + public constructor C(/*0*/ x: kotlin.Int) + public final val x: kotlin.Int + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } +} diff --git a/compiler/testData/diagnostics/tests/redeclarations/TypeAliasVsClass.kt b/compiler/testData/diagnostics/tests/redeclarations/TypeAliasVsClass.kt index 41ece3c7c86..a11ff440da8 100644 --- a/compiler/testData/diagnostics/tests/redeclarations/TypeAliasVsClass.kt +++ b/compiler/testData/diagnostics/tests/redeclarations/TypeAliasVsClass.kt @@ -6,11 +6,11 @@ typealias SomeClass = Any typealias SomeClass = Any class Outer { - class Nested + class Nested - typealias Nested = Any - typealias Nested = Any - typealias Nested = Any + typealias Nested = Any + typealias Nested = Any + typealias Nested = Any } // FILE: file2.kt diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index 7eb0a43fdca..f2ee9ae8cbc 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -13902,6 +13902,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { doTest(fileName); } + @TestMetadata("TypeAliasCtorVsFun.kt") + public void testTypeAliasCtorVsFun() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/redeclarations/TypeAliasCtorVsFun.kt"); + doTest(fileName); + } + @TestMetadata("TypeAliasVsClass.kt") public void testTypeAliasVsClass() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/redeclarations/TypeAliasVsClass.kt"); diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/TypeAliasConstructorDescriptor.kt b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/TypeAliasConstructorDescriptor.kt index a11910b17d5..0b281c7561c 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/TypeAliasConstructorDescriptor.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/TypeAliasConstructorDescriptor.kt @@ -20,25 +20,30 @@ import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.TypeSubstitutor import org.jetbrains.kotlin.types.Variance interface TypeAliasConstructorDescriptor : ConstructorDescriptor { val typeAliasDescriptor: TypeAliasDescriptor + val underlyingConstructorDescriptor: ConstructorDescriptor } class TypeAliasConstructorDescriptorImpl private constructor( override val typeAliasDescriptor: TypeAliasDescriptor, + override val underlyingConstructorDescriptor: ConstructorDescriptor, containingDeclaration: ClassDescriptor, - original: ConstructorDescriptor, + original: TypeAliasConstructorDescriptor?, annotations: Annotations, primary: Boolean, kind: Kind, source: SourceElement ) : TypeAliasConstructorDescriptor, - ConstructorDescriptorImpl(containingDeclaration, original, annotations, primary, kind, source) + ConstructorDescriptorImpl(containingDeclaration, original, annotations, + primary, kind, source) { + override fun getOriginal(): TypeAliasConstructorDescriptor = + super.getOriginal() as TypeAliasConstructorDescriptor + override fun substitute(substitutor: TypeSubstitutor): TypeAliasConstructorDescriptor = super.substitute(substitutor) as TypeAliasConstructorDescriptor @@ -70,28 +75,31 @@ class TypeAliasConstructorDescriptorImpl private constructor( } assert(newName == null) { "Renaming type alias constructor: $this" } return TypeAliasConstructorDescriptorImpl( - typeAliasDescriptor, + typeAliasDescriptor, underlyingConstructorDescriptor, newOwner as ClassDescriptor, - this, annotations, isPrimary, Kind.DECLARATION, - source) + this, + annotations, isPrimary, Kind.DECLARATION, source) } companion object { fun create( typeAliasDescriptor: TypeAliasDescriptor, - original: ConstructorDescriptor, + underlyingConstructor: ConstructorDescriptor, substitutor: TypeSubstitutor - ): TypeAliasConstructorDescriptor? { - val descriptor = TypeAliasConstructorDescriptorImpl(typeAliasDescriptor, original.containingDeclaration, original, - original.annotations, original.isPrimary, original.kind, original.source) - val valueParameters = FunctionDescriptorImpl.getSubstitutedValueParameters(descriptor, original.valueParameters, substitutor, false) - ?: return null + ): TypeAliasConstructorDescriptor? = with(underlyingConstructor) { + val typeAliasConstructor = + TypeAliasConstructorDescriptorImpl(typeAliasDescriptor, underlyingConstructor, containingDeclaration, null, + annotations, isPrimary, kind, typeAliasDescriptor.source) - descriptor.initialize(valueParameters, original.visibility, typeAliasDescriptor.typeConstructor.parameters) + val valueParameters = + FunctionDescriptorImpl.getSubstitutedValueParameters(typeAliasConstructor, valueParameters, substitutor, false) + ?: return null - descriptor.returnType = substitutor.substitute(original.returnType, Variance.OUT_VARIANCE) ?: return null + typeAliasConstructor.initialize(valueParameters, visibility, typeAliasDescriptor.typeConstructor.parameters) - return descriptor + typeAliasConstructor.returnType = substitutor.substitute(returnType, Variance.OUT_VARIANCE) ?: return null + + typeAliasConstructor } } }