diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt index 83f54d6735e..b1266f33a44 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt @@ -259,8 +259,8 @@ private fun mapSystemHasContradictionError( qualifiedAccessSource: KtSourceElement?, ): List { val errorsToIgnore = mutableSetOf() - return buildList { - for (error in diagnostic.candidate.system.errors) { + return buildList { + for (error in diagnostic.candidate.errors) { addIfNotNull( error.toDiagnostic( source, @@ -273,7 +273,7 @@ private fun mapSystemHasContradictionError( } }.ifEmpty { listOfNotNull( - diagnostic.candidate.system.errors.firstNotNullOfOrNull { + diagnostic.candidate.errors.firstNotNullOfOrNull { if (it in errorsToIgnore) return@firstNotNullOfOrNull null val message = when (it) { is NewConstraintError -> "NewConstraintError at ${it.position}: ${it.lowerType} ) { - val morePreciseDiagnosticExists = diagnostic.candidate.system.errors.any { other -> + val morePreciseDiagnosticExists = diagnostic.candidate.errors.any { other -> other is NewConstraintError && other.position.from !is FixVariableConstraintPosition<*> } if (morePreciseDiagnosticExists) return@firstNotNullOfOrNull null @@ -352,7 +352,7 @@ private fun ConstraintSystemError.toDiagnostic( } } is NotEnoughInformationForTypeParameter<*> -> { - val isDiagnosticRedundant = candidate.system.errors.any { otherError -> + val isDiagnosticRedundant = candidate.errors.any { otherError -> (otherError is ConstrainingTypeIsError && otherError.typeVariable == this.typeVariable) || otherError is NewConstraintError } diff --git a/compiler/fir/dump/src/org/jetbrains/kotlin/fir/dump/HtmlFirDump.kt b/compiler/fir/dump/src/org/jetbrains/kotlin/fir/dump/HtmlFirDump.kt index e90cb2032d9..e2d5b9bc11f 100644 --- a/compiler/fir/dump/src/org/jetbrains/kotlin/fir/dump/HtmlFirDump.kt +++ b/compiler/fir/dump/src/org/jetbrains/kotlin/fir/dump/HtmlFirDump.kt @@ -1245,7 +1245,7 @@ class HtmlFirDump internal constructor(private var linkResolver: FirLinkResolver is ConeInapplicableCandidateError -> { describeVerbose(diagnostic.candidate.symbol) br - diagnostic.candidate.system.errors.forEach { callDiagnostic -> + diagnostic.candidate.errors.forEach { callDiagnostic -> when (callDiagnostic) { is NewConstraintError -> { ident() diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Candidate.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Candidate.kt index d2b52795da1..657173c0968 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Candidate.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Candidate.kt @@ -19,6 +19,7 @@ import org.jetbrains.kotlin.fir.types.ConeTypeVariable import org.jetbrains.kotlin.resolve.calls.components.SuspendConversionStrategy import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemOperation import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage +import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintSystemError import org.jetbrains.kotlin.resolve.calls.inference.model.NewConstraintSystemImpl import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability @@ -37,13 +38,16 @@ class Candidate( ) : AbstractCandidate() { var systemInitialized: Boolean = false - override val system: NewConstraintSystemImpl by lazy(LazyThreadSafetyMode.NONE) { + val system: NewConstraintSystemImpl by lazy(LazyThreadSafetyMode.NONE) { val system = constraintSystemFactory.createConstraintSystem() system.addOtherSystem(baseSystem) systemInitialized = true system } + override val errors: List + get() = system.errors + lateinit var substitutor: ConeSubstitutor lateinit var freshVariables: List var resultingTypeForCallableReference: ConeKotlinType? = null diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirTypeResolverImpl.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirTypeResolverImpl.kt index a6b4618ff3c..97872b9e113 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirTypeResolverImpl.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirTypeResolverImpl.kt @@ -18,6 +18,10 @@ import org.jetbrains.kotlin.fir.diagnostics.ConeUnexpectedTypeArgumentsError import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind import org.jetbrains.kotlin.fir.render import org.jetbrains.kotlin.fir.resolve.* +import org.jetbrains.kotlin.fir.resolve.calls.AbstractCallInfo +import org.jetbrains.kotlin.fir.resolve.calls.AbstractCandidate +import org.jetbrains.kotlin.fir.resolve.calls.ReceiverValue +import org.jetbrains.kotlin.fir.resolve.calls.ResolutionDiagnostic import org.jetbrains.kotlin.fir.resolve.diagnostics.* import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor @@ -32,6 +36,8 @@ import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl import org.jetbrains.kotlin.fir.visibilityChecker import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.StandardClassIds +import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintSystemError +import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability import org.jetbrains.kotlin.resolve.deprecation.DeprecationLevelValue @@ -132,7 +138,7 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() { candidates.clear() } if (symbolApplicability == applicability) { - candidates.add(TypeCandidate(symbol, substitutor, diagnostic)) + candidates.add(TypeCandidate(symbol, substitutor, diagnostic, symbolApplicability)) } } @@ -160,7 +166,7 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() { TypeResolutionResult.Resolved(candidate) } candidateCount > 1 -> { - TypeResolutionResult.Ambiguity + TypeResolutionResult.Ambiguity(candidates.toList()) } candidateCount == 0 -> { TypeResolutionResult.Unresolved @@ -170,7 +176,7 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() { } sealed class TypeResolutionResult { - object Ambiguity : TypeResolutionResult() + class Ambiguity(val typeCandidates: List) : TypeResolutionResult() object Unresolved : TypeResolutionResult() class Resolved(val typeCandidate: TypeCandidate) : TypeResolutionResult() } @@ -227,19 +233,25 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() { is TypeResolutionResult.Resolved -> { result.typeCandidate.symbol to result.typeCandidate.substitutor } - TypeResolutionResult.Ambiguity -> null to null + is TypeResolutionResult.Ambiguity -> null to null TypeResolutionResult.Unresolved -> null to null } if (symbol == null || symbol !is FirClassifierSymbol<*>) { - val diagnostic = if (symbol?.fir is FirEnumEntry) { - if (isOperandOfIsOperator) { - ConeSimpleDiagnostic("'is' operator can not be applied to an enum entry.", DiagnosticKind.IsEnumEntry) - } else { - ConeSimpleDiagnostic("An enum entry should not be used as a type.", DiagnosticKind.EnumEntryAsType) + val diagnostic = when { + symbol?.fir is FirEnumEntry -> { + if (isOperandOfIsOperator) { + ConeSimpleDiagnostic("'is' operator can not be applied to an enum entry.", DiagnosticKind.IsEnumEntry) + } else { + ConeSimpleDiagnostic("An enum entry should not be used as a type.", DiagnosticKind.EnumEntryAsType) + } + } + result is TypeResolutionResult.Ambiguity -> { + ConeAmbiguityError(typeRef.qualifier.last().name, result.typeCandidates.first().applicability, result.typeCandidates) + } + else -> { + ConeUnresolvedQualifierError(typeRef.render()) } - } else { - ConeUnresolvedQualifierError(typeRef.render()) } return ConeErrorType(diagnostic) } @@ -516,10 +528,30 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() { class TypeCandidate( - val symbol: FirBasedSymbol<*>, + override val symbol: FirBasedSymbol<*>, val substitutor: ConeSubstitutor?, - val diagnostic: ConeDiagnostic? - ) { + val diagnostic: ConeDiagnostic?, + override val applicability: CandidateApplicability + ) : AbstractCandidate() { + + override val dispatchReceiverValue: ReceiverValue? + get() = null + + override val extensionReceiverValue: ReceiverValue? + get() = null + + override val explicitReceiverKind: ExplicitReceiverKind + get() = ExplicitReceiverKind.NO_EXPLICIT_RECEIVER + + override val diagnostics: List + get() = emptyList() + + override val errors: List + get() = emptyList() + + override val callInfo: AbstractCallInfo + get() = throw UnsupportedOperationException("Should not be called") + override fun equals(other: Any?): Boolean { if (this === other) return true if (other !is TypeCandidate) return false diff --git a/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/calls/AbstractCandidate.kt b/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/calls/AbstractCandidate.kt index 64dce587ea1..7097ad49346 100644 --- a/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/calls/AbstractCandidate.kt +++ b/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/calls/AbstractCandidate.kt @@ -6,7 +6,7 @@ package org.jetbrains.kotlin.fir.resolve.calls import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol -import org.jetbrains.kotlin.resolve.calls.inference.model.NewConstraintSystemImpl +import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintSystemError import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability @@ -17,6 +17,6 @@ abstract class AbstractCandidate { abstract val explicitReceiverKind: ExplicitReceiverKind abstract val callInfo: AbstractCallInfo abstract val diagnostics: List - abstract val system: NewConstraintSystemImpl + abstract val errors: List abstract val applicability: CandidateApplicability } diff --git a/compiler/testData/diagnostics/tests/imports/AllUnderImportsAmbiguity.fir.kt b/compiler/testData/diagnostics/tests/imports/AllUnderImportsAmbiguity.fir.kt new file mode 100644 index 00000000000..3fc7bcf8c6d --- /dev/null +++ b/compiler/testData/diagnostics/tests/imports/AllUnderImportsAmbiguity.fir.kt @@ -0,0 +1,17 @@ +// FILE: a.kt +package a + +class X + +// FILE: b.kt +package b + +class X + +// FILE: c.kt +package c + +import a.* +import b.* + +class Y : X diff --git a/compiler/testData/diagnostics/tests/imports/AllUnderImportsAmbiguity.kt b/compiler/testData/diagnostics/tests/imports/AllUnderImportsAmbiguity.kt index 55afdb2760e..2e7741bb479 100644 --- a/compiler/testData/diagnostics/tests/imports/AllUnderImportsAmbiguity.kt +++ b/compiler/testData/diagnostics/tests/imports/AllUnderImportsAmbiguity.kt @@ -1,4 +1,3 @@ -// FIR_IDENTICAL // FILE: a.kt package a diff --git a/compiler/testData/diagnostics/tests/imports/ExplicitImportsAmbiguity.fir.kt b/compiler/testData/diagnostics/tests/imports/ExplicitImportsAmbiguity.fir.kt new file mode 100644 index 00000000000..2324031af99 --- /dev/null +++ b/compiler/testData/diagnostics/tests/imports/ExplicitImportsAmbiguity.fir.kt @@ -0,0 +1,17 @@ +// FILE: a.kt +package a + +class X + +// FILE: b.kt +package b + +class X + +// FILE: c.kt +package c + +import a.X +import b.X + +class Y : X diff --git a/compiler/testData/diagnostics/tests/imports/ExplicitImportsAmbiguity.kt b/compiler/testData/diagnostics/tests/imports/ExplicitImportsAmbiguity.kt index 34e2ffd240a..4258ea9fc51 100644 --- a/compiler/testData/diagnostics/tests/imports/ExplicitImportsAmbiguity.kt +++ b/compiler/testData/diagnostics/tests/imports/ExplicitImportsAmbiguity.kt @@ -1,4 +1,3 @@ -// FIR_IDENTICAL // FILE: a.kt package a diff --git a/compiler/testData/diagnostics/tests/imports/NestedClassClash.fir.kt b/compiler/testData/diagnostics/tests/imports/NestedClassClash.fir.kt new file mode 100644 index 00000000000..16ad5c045d7 --- /dev/null +++ b/compiler/testData/diagnostics/tests/imports/NestedClassClash.fir.kt @@ -0,0 +1,31 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER +// FILE: a.kt +package a + +class A { + class B +} + +// FILE: b.kt +package a + +class D { + class B +} + +// FILE: c.kt +import a.A.B +import a.D.B + +fun test(b: B) { + B() +} + +// FILE: d.kt +import a.A.* +import a.D.* + +// todo ambiguvity here +fun test2(b: B) { + B() +} diff --git a/compiler/testData/diagnostics/tests/imports/NestedClassClash.kt b/compiler/testData/diagnostics/tests/imports/NestedClassClash.kt index 619d31927b6..d24cb8cf09a 100644 --- a/compiler/testData/diagnostics/tests/imports/NestedClassClash.kt +++ b/compiler/testData/diagnostics/tests/imports/NestedClassClash.kt @@ -1,4 +1,3 @@ -// FIR_IDENTICAL // !DIAGNOSTICS: -UNUSED_PARAMETER // FILE: a.kt package a diff --git a/compiler/testData/diagnostics/tests/javac/imports/AllUnderImportsAmbiguity.fir.kt b/compiler/testData/diagnostics/tests/javac/imports/AllUnderImportsAmbiguity.fir.kt index 8968a947d85..3cff0558dd1 100644 --- a/compiler/testData/diagnostics/tests/javac/imports/AllUnderImportsAmbiguity.fir.kt +++ b/compiler/testData/diagnostics/tests/javac/imports/AllUnderImportsAmbiguity.fir.kt @@ -24,4 +24,4 @@ package c import a.* import b.* -fun test(): x = d().x() +fun test(): x = d().x() diff --git a/compiler/testData/diagnostics/tests/multimodule/hiddenClass/deprecatedHiddenMultipleClasses.fir.kt b/compiler/testData/diagnostics/tests/multimodule/hiddenClass/deprecatedHiddenMultipleClasses.fir.kt index 7dcc9a702c6..ee8b6c69fec 100644 --- a/compiler/testData/diagnostics/tests/multimodule/hiddenClass/deprecatedHiddenMultipleClasses.fir.kt +++ b/compiler/testData/diagnostics/tests/multimodule/hiddenClass/deprecatedHiddenMultipleClasses.fir.kt @@ -28,7 +28,7 @@ import p1.* import p2.A import p3.* -fun test(a: A) { +fun test(a: A) { a.v1 a.v2 a.v3 @@ -39,7 +39,7 @@ import p1.* import p2.* import p3.* -fun test(a: A) { +fun test(a: A) { a.v1 a.v2 a.v3 diff --git a/compiler/testData/diagnostics/tests/multimodule/hiddenClass/sinceKotlinImportPriority.fir.kt b/compiler/testData/diagnostics/tests/multimodule/hiddenClass/sinceKotlinImportPriority.fir.kt index f0001d93574..4084d1fb3b0 100644 --- a/compiler/testData/diagnostics/tests/multimodule/hiddenClass/sinceKotlinImportPriority.fir.kt +++ b/compiler/testData/diagnostics/tests/multimodule/hiddenClass/sinceKotlinImportPriority.fir.kt @@ -23,7 +23,7 @@ class A { import p1.* import p2.* -fun test(a: A) { +fun test(a: A) { a.m1() a.m2() } diff --git a/compiler/testData/diagnostics/tests/multimodule/hiddenClass/sinceKotlinMultipleClasses.fir.kt b/compiler/testData/diagnostics/tests/multimodule/hiddenClass/sinceKotlinMultipleClasses.fir.kt index afa057415a8..949ba2ea4bc 100644 --- a/compiler/testData/diagnostics/tests/multimodule/hiddenClass/sinceKotlinMultipleClasses.fir.kt +++ b/compiler/testData/diagnostics/tests/multimodule/hiddenClass/sinceKotlinMultipleClasses.fir.kt @@ -40,7 +40,7 @@ import p1.* import p2.* import p3.* -fun test(a: A) { +fun test(a: A) { a.v1 a.v2 a.v3 diff --git a/compiler/testData/diagnostics/tests/redeclarations/RedeclaredTypeParameters.fir.kt b/compiler/testData/diagnostics/tests/redeclarations/RedeclaredTypeParameters.fir.kt index 2c1feba0c40..94155a3664d 100644 --- a/compiler/testData/diagnostics/tests/redeclarations/RedeclaredTypeParameters.fir.kt +++ b/compiler/testData/diagnostics/tests/redeclarations/RedeclaredTypeParameters.fir.kt @@ -2,5 +2,5 @@ fun <T, T> Pair() {} class P<T, T> {} -val <T, T> T.foo : Int +val <T, T> T.foo : Int get() = 1 diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/throws.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/throws.fir.kt index fe98cd6b29a..dec5b8282cf 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/throws.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/throws.fir.kt @@ -57,7 +57,7 @@ package abc4 import kotlin.Throws import kotlin.jvm.Throws -@Throws(Exception::class) +@Throws(Exception::class) fun foo1() {} @kotlin.Throws(Exception::class) @@ -66,7 +66,7 @@ fun foo2() {} @kotlin.jvm.Throws(Exception::class) fun foo3() {} -fun foo5(x: Throws) {} +fun foo5(x: Throws) {} fun foo6(x: kotlin.Throws) {} fun foo7(x: kotlin.jvm.Throws) {}