From 4737bb07dfa131d4167ae9fe0966c48ce11268c0 Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Fri, 1 Jul 2022 15:09:19 +0200 Subject: [PATCH] FIR: look for conflicting declarations more precisely --- .../diagnostics/conflictingOverloads.kt | 4 +-- .../declaration/FirConflictsChecker.kt | 14 ++++++-- .../fir/declarations/FirAnnotationUtils.kt | 9 +++++ .../fir/resolve/calls/ResolutionStages.kt | 13 +------ .../overload/ConstructorVsFunOverload.fir.kt | 4 +-- .../SingletonAndFunctionSameName.fir.kt | 2 +- .../resolveWithRedeclarationError.fir.kt | 34 ------------------- .../resolve/resolveWithRedeclarationError.kt | 1 + .../redeclarations.fir.kt | 4 +-- 9 files changed, 29 insertions(+), 56 deletions(-) delete mode 100644 compiler/testData/diagnostics/tests/resolve/resolveWithRedeclarationError.fir.kt diff --git a/compiler/fir/analysis-tests/testData/resolve/diagnostics/conflictingOverloads.kt b/compiler/fir/analysis-tests/testData/resolve/diagnostics/conflictingOverloads.kt index 249d4fba563..19ac114302b 100644 --- a/compiler/fir/analysis-tests/testData/resolve/diagnostics/conflictingOverloads.kt +++ b/compiler/fir/analysis-tests/testData/resolve/diagnostics/conflictingOverloads.kt @@ -61,9 +61,9 @@ class L { fun B.foo() {} } -fun mest() {} +fun mest() {} -class mest +class mest fun() {} diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirConflictsChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirConflictsChecker.kt index 9f4b2a09d39..2f076604e81 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirConflictsChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirConflictsChecker.kt @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.fir.analysis.checkers.declaration import org.jetbrains.kotlin.KtFakeSourceElementKind +import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.analysis.checkers.FirDeclarationInspector import org.jetbrains.kotlin.fir.analysis.checkers.FirDeclarationPresenter @@ -95,13 +96,18 @@ object FirConflictsChecker : FirBasicDeclarationChecker() { is FirCallableSymbol<*> -> session.firProvider.getFirCallableContainerFile(conflictingSymbol) else -> null } - if (containingFile == actualConflictingFile) return // TODO: rewrite local decls checker to the same logic and then remove the check + if (containingFile == actualConflictingFile && conflicting.origin == FirDeclarationOrigin.Precompiled) { + return // TODO: rewrite local decls checker to the same logic and then remove the check + } if (areCompatibleMainFunctions(declaration, containingFile, conflicting, actualConflictingFile)) return if (isExpectAndActual(declaration, conflicting)) return if ( conflicting is FirMemberDeclaration && !session.visibilityChecker.isVisible(conflicting, session, containingFile, emptyList(), null) ) return + val declarationIsLowPriority = hasLowPriorityAnnotation(declaration.annotations) + val conflictingIsLowPriority = hasLowPriorityAnnotation(conflicting.annotations) + if (declarationIsLowPriority != conflictingIsLowPriority) return declarationConflictingSymbols.getOrPut(declaration) { SmartSet.create() }.add(conflictingSymbol) } @@ -355,7 +361,7 @@ class FirNameConflictsTracker : FirNameConflictsTrackerComponent() { } } -private fun FirDeclaration.onConstructors(action: (ctor: FirConstructor) -> Unit) { +private fun FirRegularClass.onConstructors(action: (ctor: FirConstructor) -> Unit) { class ClassConstructorVisitor : FirVisitorVoid() { override fun visitElement(element: FirElement) {} @@ -370,7 +376,9 @@ private fun FirDeclaration.onConstructors(action: (ctor: FirConstructor) -> Unit override fun visitSimpleFunction(simpleFunction: FirSimpleFunction) {} } - acceptChildren(ClassConstructorVisitor()) + if (classKind != ClassKind.OBJECT && classKind != ClassKind.ENUM_ENTRY) { + acceptChildren(ClassConstructorVisitor()) + } } diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/declarations/FirAnnotationUtils.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/declarations/FirAnnotationUtils.kt index 5ea25a5309d..28aeabb1186 100644 --- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/declarations/FirAnnotationUtils.kt +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/declarations/FirAnnotationUtils.kt @@ -21,6 +21,7 @@ import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.fir.types.coneTypeSafe import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.StandardClassIds @@ -186,3 +187,11 @@ val FirAnnotation.resolved: Boolean if (this !is FirAnnotationCall) return true return calleeReference is FirResolvedNamedReference || calleeReference is FirErrorNamedReference } + +private val LOW_PRIORITY_IN_OVERLOAD_RESOLUTION_CLASS_ID: ClassId = + ClassId(FqName("kotlin.internal"), Name.identifier("LowPriorityInOverloadResolution")) + +fun hasLowPriorityAnnotation(annotations: List) = annotations.any { + val lookupTag = it.annotationTypeRef.coneTypeSafe()?.lookupTag ?: return@any false + lookupTag.classId == LOW_PRIORITY_IN_OVERLOAD_RESOLUTION_CLASS_ID +} diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt index 4b619042077..89816bd09dd 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt @@ -7,7 +7,6 @@ package org.jetbrains.kotlin.fir.resolve.calls import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.descriptors.Modality -import org.jetbrains.kotlin.fir.FirVisibilityChecker import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.utils.isInfix import org.jetbrains.kotlin.fir.declarations.utils.isOperator @@ -33,8 +32,6 @@ import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.visibilityChecker import org.jetbrains.kotlin.name.ClassId -import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.calls.inference.isSubtypeConstraintCompatible import org.jetbrains.kotlin.resolve.calls.inference.model.SimpleConstraintSystemConstraintPosition import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind.* @@ -542,9 +539,6 @@ internal object CheckVisibility : CheckerStage() { } internal object CheckLowPriorityInOverloadResolution : CheckerStage() { - private val LOW_PRIORITY_IN_OVERLOAD_RESOLUTION_CLASS_ID: ClassId = - ClassId(FqName("kotlin.internal"), Name.identifier("LowPriorityInOverloadResolution")) - override suspend fun check(candidate: Candidate, callInfo: CallInfo, sink: CheckerSink, context: ResolutionContext) { val annotations = when (val fir = candidate.symbol.fir) { is FirSimpleFunction -> fir.annotations @@ -553,12 +547,7 @@ internal object CheckLowPriorityInOverloadResolution : CheckerStage() { else -> return } - val hasLowPriorityAnnotation = annotations.any { - val lookupTag = it.annotationTypeRef.coneTypeSafe()?.lookupTag ?: return@any false - lookupTag.classId == LOW_PRIORITY_IN_OVERLOAD_RESOLUTION_CLASS_ID - } - - if (hasLowPriorityAnnotation) { + if (hasLowPriorityAnnotation(annotations)) { sink.reportDiagnostic(ResolvedWithLowPriority) } } diff --git a/compiler/testData/diagnostics/tests/overload/ConstructorVsFunOverload.fir.kt b/compiler/testData/diagnostics/tests/overload/ConstructorVsFunOverload.fir.kt index 24e7c934b48..02af6a37797 100644 --- a/compiler/testData/diagnostics/tests/overload/ConstructorVsFunOverload.fir.kt +++ b/compiler/testData/diagnostics/tests/overload/ConstructorVsFunOverload.fir.kt @@ -2,9 +2,9 @@ package constructorVsFun -class a() { } +class a() { } -fun a() = 1 +fun a() = 1 class Tram { fun f() { } diff --git a/compiler/testData/diagnostics/tests/redeclarations/SingletonAndFunctionSameName.fir.kt b/compiler/testData/diagnostics/tests/redeclarations/SingletonAndFunctionSameName.fir.kt index 612aac4f372..4f25e8f38d6 100644 --- a/compiler/testData/diagnostics/tests/redeclarations/SingletonAndFunctionSameName.fir.kt +++ b/compiler/testData/diagnostics/tests/redeclarations/SingletonAndFunctionSameName.fir.kt @@ -10,7 +10,7 @@ object Foo { fun En() = 239 -enum class En { +enum class En { ENTRY, SUBCLASS { }; diff --git a/compiler/testData/diagnostics/tests/resolve/resolveWithRedeclarationError.fir.kt b/compiler/testData/diagnostics/tests/resolve/resolveWithRedeclarationError.fir.kt deleted file mode 100644 index 342ef2b152c..00000000000 --- a/compiler/testData/diagnostics/tests/resolve/resolveWithRedeclarationError.fir.kt +++ /dev/null @@ -1,34 +0,0 @@ -//If this test hangs, it means something is broken. -package c - -fun z(view: () -> Unit) {} - -fun x() = z { z { z { z { z { z { z { z { } } } } } } } } -fun x() = z { z { z { z { z { z { z { z { } } } } } } } } -fun x() = z { z { z { z { z { z { z { z { } } } } } } } } -fun x() = z { z { z { z { z { z { z { z { } } } } } } } } -fun x() = z { z { z { z { z { z { z { z { } } } } } } } } -fun x() = z { z { z { z { z { z { z { z { } } } } } } } } -fun x() = z { z { z { z { z { z { z { z { } } } } } } } } -fun x() = z { z { z { z { z { z { z { z { } } } } } } } } -fun x() = z { z { z { z { z { z { z { z { } } } } } } } } -fun x() = z { z { z { z { z { z { z { z { } } } } } } } } -fun x() = z { z { z { z { z { z { z { z { } } } } } } } } -fun x() = z { z { z { z { z { z { z { z { } } } } } } } } -fun x() = z { z { z { z { z { z { z { z { } } } } } } } } -fun x() = z { z { z { z { z { z { z { z { } } } } } } } } -fun x() = z { z { z { z { z { z { z { z { } } } } } } } } -fun x() = z { z { z { z { z { z { z { z { } } } } } } } } -fun x() = z { z { z { z { z { z { z { z { } } } } } } } } -fun x() = z { z { z { z { z { z { z { z { } } } } } } } } -fun x() = z { z { z { z { z { z { z { z { } } } } } } } } -fun x() = z { z { z { z { z { z { z { z { } } } } } } } } -fun x() = z { z { z { z { z { z { z { z { } } } } } } } } -fun x() = z { z { z { z { z { z { z { z { } } } } } } } } -fun x() = z { z { z { z { z { z { z { z { } } } } } } } } -fun x() = z { z { z { z { z { z { z { z { } } } } } } } } -fun x() = z { z { z { z { z { z { z { z { } } } } } } } } -fun x() = z { z { z { z { z { z { z { z { } } } } } } } } -fun x() = z { z { z { z { z { z { z { z { } } } } } } } } - -class x() {} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/resolve/resolveWithRedeclarationError.kt b/compiler/testData/diagnostics/tests/resolve/resolveWithRedeclarationError.kt index 5cbc21dd077..dd1bfe249af 100644 --- a/compiler/testData/diagnostics/tests/resolve/resolveWithRedeclarationError.kt +++ b/compiler/testData/diagnostics/tests/resolve/resolveWithRedeclarationError.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL //If this test hangs, it means something is broken. package c diff --git a/compiler/testData/diagnostics/tests/secondaryConstructors/redeclarations.fir.kt b/compiler/testData/diagnostics/tests/secondaryConstructors/redeclarations.fir.kt index 96e12c13c85..adcde08d4c4 100644 --- a/compiler/testData/diagnostics/tests/secondaryConstructors/redeclarations.fir.kt +++ b/compiler/testData/diagnostics/tests/secondaryConstructors/redeclarations.fir.kt @@ -7,10 +7,10 @@ class A(x: String = "", y: String = "") { } class B { - constructor(x: Int) + constructor(x: Int) } -fun B(x: Int) {} +fun B(x: Int) {} class Outer { class A(x: String = "", y: String = "") {