From 454ae3b17afc30e4b3030afe5357f89af018c784 Mon Sep 17 00:00:00 2001 From: Tianyu Geng Date: Fri, 9 Apr 2021 21:26:07 +0300 Subject: [PATCH] FIR checker: report UNSAFE_CALL for overloaded function calls Previously if an unsafe call is to an overloaded function, FIR checkers report NONE_APPLICABLE. This change instead report them as UNSAFE_CALL or its variants. --- .../FirDestructuringDeclarationChecker.kt | 2 +- .../checkers/expression/FirForLoopChecker.kt | 4 +- .../coneDiagnosticToFirDiagnostic.kt | 37 ++++++++--------- .../jetbrains/kotlin/fir/dump/HtmlFirDump.kt | 2 +- .../jetbrains/kotlin/fir/FirCallResolver.kt | 4 +- .../fir/resolve/diagnostics/FirDiagnostics.kt | 5 ++- .../tests/BinaryCallsOnNullableValues.fir.kt | 8 ++-- .../diagnostics/tests/Nullability.fir.kt | 12 +++--- .../InfixCallNullability.fir.kt | 41 ------------------- .../InfixCallNullability.kt | 1 + .../NullableNothingIsExactlyNull.fir.kt | 4 +- .../nullabilityAndSmartCasts/kt2216.fir.kt | 2 +- .../nullabilityAndSmartCasts/kt362.fir.kt | 4 +- ...ullableReceiverWithOverloadedMethod.fir.kt | 6 +-- ...leSmartcastWithOverloadedExtensions.fir.kt | 2 +- .../tests/regressions/kt282.fir.kt | 19 --------- .../diagnostics/tests/regressions/kt282.kt | 1 + .../specialConstructions/elvisAsCall.fir.kt | 4 +- .../smartCasts/objectLiterals/exclexcl.fir.kt | 2 +- .../objectLiterals/exclexclArgument.fir.kt | 2 +- .../objectLiterals/exclexclTwoArgument.fir.kt | 2 +- .../varnotnull/plusplusMinusminus.fir.kt | 2 +- .../smartCasts/varnotnull/varIntNull.fir.kt | 2 +- .../analysis/smartcasts/neg/10.fir.kt | 24 +++++------ .../analysis/smartcasts/neg/2.fir.kt | 10 ++--- .../analysis/smartcasts/neg/3.fir.kt | 10 ++--- .../diagnostics/notLinked/dfa/neg/43.fir.kt | 2 +- .../org/jetbrains/kotlin/idea/fir/FirUtils.kt | 2 +- .../fir/components/KtFirReferenceShortener.kt | 2 +- .../references/FirReferenceResolveHelper.kt | 7 +++- 30 files changed, 83 insertions(+), 142 deletions(-) delete mode 100644 compiler/testData/diagnostics/tests/nullabilityAndSmartCasts/InfixCallNullability.fir.kt delete mode 100644 compiler/testData/diagnostics/tests/regressions/kt282.fir.kt diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDestructuringDeclarationChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDestructuringDeclarationChecker.kt index 82b130b8c30..59e2807ce45 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDestructuringDeclarationChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDestructuringDeclarationChecker.kt @@ -165,7 +165,7 @@ object FirDestructuringDeclarationChecker : FirPropertyChecker() { source, FirErrors.COMPONENT_FUNCTION_AMBIGUITY, diagnostic.name, - diagnostic.candidates, + diagnostic.candidates.map { it.symbol }, context ) } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirForLoopChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirForLoopChecker.kt index c8f765a7787..96592b11645 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirForLoopChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirForLoopChecker.kt @@ -95,9 +95,9 @@ object FirForLoopChecker : FirBlockChecker() { is FirErrorNamedReference -> { when (val diagnostic = calleeReference.diagnostic) { is ConeAmbiguityError -> if (diagnostic.applicability.isSuccess) { - reporter.reportOn(reportSource, ambiguityFactory, diagnostic.candidates, context) + reporter.reportOn(reportSource, ambiguityFactory, diagnostic.candidates.map { it.symbol }, context) } else if (noneApplicableFactory != null) { - reporter.reportOn(reportSource, noneApplicableFactory, diagnostic.candidates, context) + reporter.reportOn(reportSource, noneApplicableFactory, diagnostic.candidates.map { it.symbol }, context) } is ConeUnresolvedNameError -> { reporter.reportOn(reportSource, missingFactory, context) 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 194858646f0..e106c06d059 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 @@ -16,9 +16,10 @@ import org.jetbrains.kotlin.fir.diagnostics.* import org.jetbrains.kotlin.fir.resolve.calls.* import org.jetbrains.kotlin.fir.resolve.diagnostics.* import org.jetbrains.kotlin.fir.symbols.impl.FirBackingFieldSymbol -import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.lexer.KtTokens +import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability import org.jetbrains.kotlin.resolve.calls.tower.isSuccess +import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance import org.jetbrains.kotlin.utils.addToStdlib.safeAs private fun ConeDiagnostic.toFirDiagnostic( @@ -30,10 +31,14 @@ private fun ConeDiagnostic.toFirDiagnostic( is ConeUnresolvedNameError -> FirErrors.UNRESOLVED_REFERENCE.on(source, this.name.asString()) is ConeUnresolvedQualifierError -> FirErrors.UNRESOLVED_REFERENCE.on(source, this.qualifier) is ConeHiddenCandidateError -> FirErrors.HIDDEN.on(source, this.candidateSymbol) - is ConeAmbiguityError -> if (!this.applicability.isSuccess) { - FirErrors.NONE_APPLICABLE.on(source, this.candidates) + is ConeAmbiguityError -> if (this.applicability.isSuccess) { + FirErrors.OVERLOAD_RESOLUTION_AMBIGUITY.on(source, this.candidates.map { it.symbol }) + } else if (this.applicability == CandidateApplicability.UNSAFE_CALL) { + val candidate = candidates.first { it.currentApplicability == CandidateApplicability.UNSAFE_CALL } + val unsafeCall = candidate.diagnostics.firstIsInstance() + mapUnsafeCallError(candidate, unsafeCall, source, qualifiedAccessSource) } else { - FirErrors.OVERLOAD_RESOLUTION_AMBIGUITY.on(source, this.candidates) + FirErrors.NONE_APPLICABLE.on(source, this.candidates.map { it.symbol }) } is ConeOperatorAmbiguityError -> FirErrors.ASSIGN_OPERATOR_AMBIGUITY.on(source, this.candidates) is ConeVariableExpectedError -> FirErrors.VARIABLE_EXPECTED.on(source) @@ -71,30 +76,20 @@ fun ConeDiagnostic.toFirDiagnostics( return listOfNotNull(toFirDiagnostic(source, qualifiedAccessSource)) } -private fun ConeKotlinType.isEffectivelyNotNull(): Boolean { - return when (this) { - is ConeClassLikeType -> !isMarkedNullable - is ConeTypeParameterType -> !isMarkedNullable && lookupTag.typeParameterSymbol.fir.bounds.any { - it.coneTypeSafe()?.isEffectivelyNotNull() == true - } - else -> false - } -} - private fun mapUnsafeCallError( - diagnostic: ConeInapplicableCandidateError, - source: FirSourceElement, + candidate: Candidate, rootCause: UnsafeCall, + source: FirSourceElement, qualifiedAccessSource: FirSourceElement?, ): FirDiagnostic<*> { - if (diagnostic.candidate.callInfo.isImplicitInvoke) { + if (candidate.callInfo.isImplicitInvoke) { return FirErrors.UNSAFE_IMPLICIT_INVOKE_CALL.on(source, rootCause.actualType) } - val candidateFunction = diagnostic.candidate.symbol.fir as? FirSimpleFunction + val candidateFunction = candidate.symbol.fir as? FirSimpleFunction val candidateFunctionName = candidateFunction?.name - val left = diagnostic.candidate.callInfo.explicitReceiver - val right = diagnostic.candidate.callInfo.argumentList.arguments.singleOrNull() + val left = candidate.callInfo.explicitReceiver + val right = candidate.callInfo.argumentList.arguments.singleOrNull() if (left != null && right != null && source.elementType == KtNodeTypes.OPERATION_REFERENCE && (candidateFunction?.isOperator == true || candidateFunction?.isInfix == true) @@ -145,7 +140,7 @@ private fun mapInapplicableCandidateError( rootCause.argument.source ?: source, rootCause.argument.name.asString() ) - is UnsafeCall -> mapUnsafeCallError(diagnostic, source, rootCause, qualifiedAccessSource) + is UnsafeCall -> mapUnsafeCallError(diagnostic.candidate, rootCause, source, qualifiedAccessSource) else -> null } }.ifEmpty { listOf(FirErrors.INAPPLICABLE_CANDIDATE.on(source, diagnostic.candidate.symbol)) } 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 3f8c40ec339..68be74f52c1 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 @@ -1258,7 +1258,7 @@ class HtmlFirDump internal constructor(private var linkResolver: FirLinkResolver +"Ambiguity: " br for (candidate in diagnostic.candidates) { - describeVerbose(candidate) + describeVerbose(candidate.symbol) br } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt index 03da23495d1..487a8dc79f1 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt @@ -289,7 +289,7 @@ class FirCallResolver( if (resolvedCallableReferenceAtom.hasBeenPostponed) { val errorReference = buildErrorReference( info, - ConeAmbiguityError(info.name, applicability, reducedCandidates.map { it.symbol }), + ConeAmbiguityError(info.name, applicability, reducedCandidates), callableReferenceAccess.source ) resolvedCallableReferenceAtom.resultingReference = errorReference @@ -530,7 +530,7 @@ class FirCallResolver( candidates.size > 1 -> buildErrorReference( callInfo, - ConeAmbiguityError(name, applicability, candidates.map { it.symbol }), + ConeAmbiguityError(name, applicability, candidates), source ) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/diagnostics/FirDiagnostics.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/diagnostics/FirDiagnostics.kt index 9807b76df51..7a55b541285 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/diagnostics/FirDiagnostics.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/diagnostics/FirDiagnostics.kt @@ -57,8 +57,9 @@ class ConeArgumentTypeMismatchCandidateError( get() = "Type mismatch. Expected: $expectedType, Actual: $actualType" } -class ConeAmbiguityError(val name: Name, val applicability: CandidateApplicability, val candidates: Collection>) : ConeDiagnostic() { - override val reason: String get() = "Ambiguity: $name, ${candidates.map { describeSymbol(it) }}" +class ConeAmbiguityError(val name: Name, val applicability: CandidateApplicability, val candidates: Collection) : + ConeDiagnostic() { + override val reason: String get() = "Ambiguity: $name, ${candidates.map { describeSymbol(it.symbol) }}" } class ConeOperatorAmbiguityError(val candidates: Collection>) : ConeDiagnostic() { diff --git a/compiler/testData/diagnostics/tests/BinaryCallsOnNullableValues.fir.kt b/compiler/testData/diagnostics/tests/BinaryCallsOnNullableValues.fir.kt index 339a7a6219d..530b46562ba 100644 --- a/compiler/testData/diagnostics/tests/BinaryCallsOnNullableValues.fir.kt +++ b/compiler/testData/diagnostics/tests/BinaryCallsOnNullableValues.fir.kt @@ -6,9 +6,9 @@ class A() { fun f(): Unit { var x: Int? = 1 x = null - x + 1 - x plus 1 - x < 1 + x + 1 + x plus 1 + x < 1 x += 1 x == 1 @@ -22,7 +22,7 @@ fun f(): Unit { x === 1 x !== 1 - x..2 + x..2 x in 1..2 val y : Boolean? = true diff --git a/compiler/testData/diagnostics/tests/Nullability.fir.kt b/compiler/testData/diagnostics/tests/Nullability.fir.kt index 0d16457de5f..4fa6157c966 100644 --- a/compiler/testData/diagnostics/tests/Nullability.fir.kt +++ b/compiler/testData/diagnostics/tests/Nullability.fir.kt @@ -44,7 +44,7 @@ fun test() { if (out == null || out.println(0) == Unit) { out?.println(1) - out.println(1) + out.println(1) } else { out.println(2) @@ -66,11 +66,11 @@ fun test() { if (1 == 2 || out != null && out.println(1) == Unit) { out?.println(2); - out.println(2); + out.println(2); } else { out?.println(3) - out.println(3) + out.println(3) } out?.println() @@ -103,7 +103,7 @@ fun test() { if (out == null || out.println(0) == Unit) { out?.println(1) - out.println(1) + out.println(1) } else { out.println(2) @@ -127,11 +127,11 @@ fun test() { if (1 == 2 || out != null && out.println(1) == Unit) { out?.println(2); - out.println(2); + out.println(2); } else { out?.println(3) - out.println(3) + out.println(3) } if (1 > 2) { diff --git a/compiler/testData/diagnostics/tests/nullabilityAndSmartCasts/InfixCallNullability.fir.kt b/compiler/testData/diagnostics/tests/nullabilityAndSmartCasts/InfixCallNullability.fir.kt deleted file mode 100644 index 0e415d6bb24..00000000000 --- a/compiler/testData/diagnostics/tests/nullabilityAndSmartCasts/InfixCallNullability.fir.kt +++ /dev/null @@ -1,41 +0,0 @@ -// !WITH_NEW_INFERENCE -class A() { - operator infix fun plus(i : Int) {} - operator fun unaryMinus() {} - operator infix fun contains(a : Any?) : Boolean = true -} - -operator infix fun A.div(i : Int) {} -operator infix fun A?.times(i : Int) {} - -fun test(x : Int?, a : A?) { - x.plus(1) - x?.plus(1) - x + 1 - -x - x.unaryMinus() - x?.unaryMinus() - - a.plus(1) - a?.plus(1) - a plus 1 - a + 1 - -a - a.unaryMinus() - a?.unaryMinus() - - a.div(1) - a / 1 - a div 1 - a?.div(1) - - a.times(1) - a * 1 - a times 1 - a?.times(1) - - 1 in a - a contains 1 - a.contains(1) - a?.contains(1) -} diff --git a/compiler/testData/diagnostics/tests/nullabilityAndSmartCasts/InfixCallNullability.kt b/compiler/testData/diagnostics/tests/nullabilityAndSmartCasts/InfixCallNullability.kt index 65fc2ab06c0..36e6c2d8c91 100644 --- a/compiler/testData/diagnostics/tests/nullabilityAndSmartCasts/InfixCallNullability.kt +++ b/compiler/testData/diagnostics/tests/nullabilityAndSmartCasts/InfixCallNullability.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !WITH_NEW_INFERENCE class A() { operator infix fun plus(i : Int) {} diff --git a/compiler/testData/diagnostics/tests/nullabilityAndSmartCasts/NullableNothingIsExactlyNull.fir.kt b/compiler/testData/diagnostics/tests/nullabilityAndSmartCasts/NullableNothingIsExactlyNull.fir.kt index d5b70b57e5f..99fdd96492f 100644 --- a/compiler/testData/diagnostics/tests/nullabilityAndSmartCasts/NullableNothingIsExactlyNull.fir.kt +++ b/compiler/testData/diagnostics/tests/nullabilityAndSmartCasts/NullableNothingIsExactlyNull.fir.kt @@ -2,7 +2,7 @@ fun test() { val out : Int? = null val x : Nothing? = null if (out != x) - out.plus(1) + out.plus(1) if (out == x) return - out.plus(1) + out.plus(1) } diff --git a/compiler/testData/diagnostics/tests/nullabilityAndSmartCasts/kt2216.fir.kt b/compiler/testData/diagnostics/tests/nullabilityAndSmartCasts/kt2216.fir.kt index a5f67469b54..854e2281788 100644 --- a/compiler/testData/diagnostics/tests/nullabilityAndSmartCasts/kt2216.fir.kt +++ b/compiler/testData/diagnostics/tests/nullabilityAndSmartCasts/kt2216.fir.kt @@ -16,7 +16,7 @@ fun foo() { val y: Int? = 0 val z: Int? = 0 bar(if (y != null) y else z, y) - y + 2 + y + 2 baz(y, y, if (y == null) return else y, y) baz(y, z!!, z, y) } diff --git a/compiler/testData/diagnostics/tests/nullabilityAndSmartCasts/kt362.fir.kt b/compiler/testData/diagnostics/tests/nullabilityAndSmartCasts/kt362.fir.kt index 460e89813aa..c4cbdd17d14 100644 --- a/compiler/testData/diagnostics/tests/nullabilityAndSmartCasts/kt362.fir.kt +++ b/compiler/testData/diagnostics/tests/nullabilityAndSmartCasts/kt362.fir.kt @@ -6,11 +6,11 @@ package example fun test() { val p = test.Public() if (p.public is Int) p.public + 1 - if (p.protected is Int) p.protected + 1 + if (p.protected is Int) p.protected + 1 if (p.internal is Int) p.internal + 1 val i = test.Internal() if (i.public is Int) i.public + 1 - if (i.protected is Int) i.protected + 1 + if (i.protected is Int) i.protected + 1 if (i.internal is Int) i.internal + 1 } diff --git a/compiler/testData/diagnostics/tests/nullabilityAndSmartCasts/nullableReceiverWithOverloadedMethod.fir.kt b/compiler/testData/diagnostics/tests/nullabilityAndSmartCasts/nullableReceiverWithOverloadedMethod.fir.kt index 70a83ede2b7..34eb02f4978 100644 --- a/compiler/testData/diagnostics/tests/nullabilityAndSmartCasts/nullableReceiverWithOverloadedMethod.fir.kt +++ b/compiler/testData/diagnostics/tests/nullabilityAndSmartCasts/nullableReceiverWithOverloadedMethod.fir.kt @@ -13,15 +13,15 @@ class B { fun f() { a = A() - a.f(true) - takeInt(a.f("")) + a.f(true) + takeInt(a.f("")) a.f() } fun g() { takeInt(if (3 > 2) { a = A() - a.f(true) + a.f(true) } else { 6 }) diff --git a/compiler/testData/diagnostics/tests/nullabilityAndSmartCasts/unstableSmartcastWithOverloadedExtensions.fir.kt b/compiler/testData/diagnostics/tests/nullabilityAndSmartCasts/unstableSmartcastWithOverloadedExtensions.fir.kt index dc944fc6d17..8aa89b44288 100644 --- a/compiler/testData/diagnostics/tests/nullabilityAndSmartCasts/unstableSmartcastWithOverloadedExtensions.fir.kt +++ b/compiler/testData/diagnostics/tests/nullabilityAndSmartCasts/unstableSmartcastWithOverloadedExtensions.fir.kt @@ -9,6 +9,6 @@ var a: A? = null fun smartCastInterference(b: B) { if (a != null) { - a.foo(b) + a.foo(b) } } diff --git a/compiler/testData/diagnostics/tests/regressions/kt282.fir.kt b/compiler/testData/diagnostics/tests/regressions/kt282.fir.kt deleted file mode 100644 index 3819249ce58..00000000000 --- a/compiler/testData/diagnostics/tests/regressions/kt282.fir.kt +++ /dev/null @@ -1,19 +0,0 @@ -// !WITH_NEW_INFERENCE -// KT-282 Nullability in extension functions and in binary calls - -class Set { - operator fun contains(x : Int) : Boolean = true -} - -operator fun Set?.plus(x : Int) : Int = 1 - -operator fun Int?.contains(x : Int) : Boolean = false - -fun f(): Unit { - var set : Set? = null - val i : Int? = null - i + 1 - set + 1 - 1 in set - 1 in 2 -} diff --git a/compiler/testData/diagnostics/tests/regressions/kt282.kt b/compiler/testData/diagnostics/tests/regressions/kt282.kt index c0a3d9c89e2..b8c0744fcec 100644 --- a/compiler/testData/diagnostics/tests/regressions/kt282.kt +++ b/compiler/testData/diagnostics/tests/regressions/kt282.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !WITH_NEW_INFERENCE // KT-282 Nullability in extension functions and in binary calls diff --git a/compiler/testData/diagnostics/tests/resolve/specialConstructions/elvisAsCall.fir.kt b/compiler/testData/diagnostics/tests/resolve/specialConstructions/elvisAsCall.fir.kt index f5e5e217963..575c13f78ca 100644 --- a/compiler/testData/diagnostics/tests/resolve/specialConstructions/elvisAsCall.fir.kt +++ b/compiler/testData/diagnostics/tests/resolve/specialConstructions/elvisAsCall.fir.kt @@ -23,13 +23,13 @@ fun testDataFlowInfo1(a: Int?, b: Int?) { val c: Int = a ?: b!! doInt(c) // b is nullable if a != null - b + 1 + b + 1 } fun testDataFlowInfo2(a: Int?, b: Int?) { doInt(a ?: b!!) // b is nullable if a != null - b + 1 + b + 1 } fun testTypeMismatch(a: String?, b: Any) { diff --git a/compiler/testData/diagnostics/tests/smartCasts/objectLiterals/exclexcl.fir.kt b/compiler/testData/diagnostics/tests/smartCasts/objectLiterals/exclexcl.fir.kt index 8ce2be9293b..3fd3429e133 100644 --- a/compiler/testData/diagnostics/tests/smartCasts/objectLiterals/exclexcl.fir.kt +++ b/compiler/testData/diagnostics/tests/smartCasts/objectLiterals/exclexcl.fir.kt @@ -16,7 +16,7 @@ fun foo(): Int { k.run() val d: Int = c // a is not null because of k constructor, but we do not know it - return a + d + return a + d } else return -1 } diff --git a/compiler/testData/diagnostics/tests/smartCasts/objectLiterals/exclexclArgument.fir.kt b/compiler/testData/diagnostics/tests/smartCasts/objectLiterals/exclexclArgument.fir.kt index ffe2b8b8155..d7f6c5c053d 100644 --- a/compiler/testData/diagnostics/tests/smartCasts/objectLiterals/exclexclArgument.fir.kt +++ b/compiler/testData/diagnostics/tests/smartCasts/objectLiterals/exclexclArgument.fir.kt @@ -11,7 +11,7 @@ fun foo(): Int { } k.run() val d: Int = c - return a + d + return a + d } else return -1 } diff --git a/compiler/testData/diagnostics/tests/smartCasts/objectLiterals/exclexclTwoArgument.fir.kt b/compiler/testData/diagnostics/tests/smartCasts/objectLiterals/exclexclTwoArgument.fir.kt index 41d7c35a27d..994dcfab512 100644 --- a/compiler/testData/diagnostics/tests/smartCasts/objectLiterals/exclexclTwoArgument.fir.kt +++ b/compiler/testData/diagnostics/tests/smartCasts/objectLiterals/exclexclTwoArgument.fir.kt @@ -15,7 +15,7 @@ fun foo(): Int { } k.run() val d: Int = c - return a + d + return a + d } else return -1 } diff --git a/compiler/testData/diagnostics/tests/smartCasts/varnotnull/plusplusMinusminus.fir.kt b/compiler/testData/diagnostics/tests/smartCasts/varnotnull/plusplusMinusminus.fir.kt index 6990adf9fa8..169ccfa437c 100644 --- a/compiler/testData/diagnostics/tests/smartCasts/varnotnull/plusplusMinusminus.fir.kt +++ b/compiler/testData/diagnostics/tests/smartCasts/varnotnull/plusplusMinusminus.fir.kt @@ -15,7 +15,7 @@ fun bar(arg: Long?): Long { return i-- + i } if (i++ == 7L) { - return i++ + i + return i++ + i } return 0L } diff --git a/compiler/testData/diagnostics/tests/smartCasts/varnotnull/varIntNull.fir.kt b/compiler/testData/diagnostics/tests/smartCasts/varnotnull/varIntNull.fir.kt index 084c76726f7..078a6734872 100644 --- a/compiler/testData/diagnostics/tests/smartCasts/varnotnull/varIntNull.fir.kt +++ b/compiler/testData/diagnostics/tests/smartCasts/varnotnull/varIntNull.fir.kt @@ -2,5 +2,5 @@ fun foo(): Int { var i: Int? = 42 i = null - return i + 1 + return i + 1 } diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/10.fir.kt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/10.fir.kt index 99c0fdb7cca..f267c61b863 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/10.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/10.fir.kt @@ -346,22 +346,22 @@ class case_14_class { if (!funWithReturnsTrueAndInvertCondition(value_1 is Float? && value_1 != null && value_2 != null && o.prop_1 != null)) { println(value_1.dec()) println(value_2?.toByte()) - println(o.prop_1.plus(3)) + println(o.prop_1.plus(3)) } if (funWithReturnsFalse(value_1 !is Float? || value_1 == null || value_2 == null || o.prop_1 == null || this.prop_1 == null)) { println(value_1.dec()) println(value_2?.toByte()) - println(o.prop_1.plus(3)) + println(o.prop_1.plus(3)) } if (funWithReturnsNotNull(value_1 !is Float? || value_1 == null || value_2 == null || o.prop_1 == null || this.prop_1 == null) == null) { println(value_1.dec()) println(value_2?.toByte()) - println(o.prop_1.plus(3)) + println(o.prop_1.plus(3)) } if (funWithReturnsNull(value_1 !is Float? || value_1 == null || value_2 == null || o.prop_1 == null || this.prop_1 == null) != null) { println(value_1.dec()) println(value_2?.toByte()) - println(o.prop_1.plus(3)) + println(o.prop_1.plus(3)) } } } @@ -415,26 +415,26 @@ class case_17_class { if (contracts.case_17_1(value_1, value_2, o.prop_1, this.prop_1)) { println(value_1.dec()) println(value_2?.toByte()) - println(o.prop_1.plus(3)) - println(this.prop_1.plus(3)) + println(o.prop_1.plus(3)) + println(this.prop_1.plus(3)) } if (contracts.case_17_2(value_1, value_2, o.prop_1, this.prop_1)) { println(value_1.dec()) println(value_2?.toByte()) - println(o.prop_1.plus(3)) - println(this.prop_1.plus(3)) + println(o.prop_1.plus(3)) + println(this.prop_1.plus(3)) } if (contracts.case_17_3(value_1, value_2, o.prop_1, this.prop_1) == null) { println(value_1.dec()) println(value_2?.toByte()) - println(o.prop_1.plus(3)) - println(this.prop_1.plus(3)) + println(o.prop_1.plus(3)) + println(this.prop_1.plus(3)) } if (contracts.case_17_4(value_1, value_2, o.prop_1, this.prop_1) != null) { println(value_1.dec()) println(value_2?.toByte()) - println(o.prop_1.plus(3)) - println(this.prop_1.plus(3)) + println(o.prop_1.plus(3)) + println(this.prop_1.plus(3)) } } } diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/2.fir.kt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/2.fir.kt index b4a1d35cdb8..d71d493507c 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/2.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/2.fir.kt @@ -38,7 +38,7 @@ class case_5_class { funWithReturns(value_1 !is Float? || value_1 == null || value_2 == null || o.prop_1 == null) println(value_1.dec()) println(value_2?.toByte()) - println(o.prop_1.plus(3)) + println(o.prop_1.plus(3)) } } @@ -131,22 +131,22 @@ class case_10_class { if (funWithReturnsTrue(value_1 !is Float? || value_1 == null || value_2 == null || o.prop_1 == null || this.prop_1 == null)) { println(value_1.dec()) println(value_2?.toByte()) - println(o.prop_1.plus(3)) + println(o.prop_1.plus(3)) } if (!funWithReturnsFalse(value_1 !is Float? || value_1 == null || value_2 == null || o.prop_1 == null || this.prop_1 == null)) { println(value_1.dec()) println(value_2?.toByte()) - println(o.prop_1.plus(3)) + println(o.prop_1.plus(3)) } if (funWithReturnsNotNull(value_1 !is Float? || value_1 == null || value_2 == null || o.prop_1 == null || this.prop_1 == null) != null) { println(value_1.dec()) println(value_2?.toByte()) - println(o.prop_1.plus(3)) + println(o.prop_1.plus(3)) } if (funWithReturnsNull(value_1 !is Float? || value_1 == null || value_2 == null || o.prop_1 == null || this.prop_1 == null) == null) { println(value_1.dec()) println(value_2?.toByte()) - println(o.prop_1.plus(3)) + println(o.prop_1.plus(3)) } } } diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/3.fir.kt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/3.fir.kt index 768dadde6bb..0799c972cd4 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/3.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/3.fir.kt @@ -105,7 +105,7 @@ class case_3_class { contracts.case_3(value_1, value_2, o.prop_1, this.prop_1) println(value_1.dec()) println(value_2?.toByte()) - println(o.prop_1.plus(3)) + println(o.prop_1.plus(3)) } } @@ -158,22 +158,22 @@ class case_6_class { if (contracts.case_6_1(value_1, value_2, o.prop_1, this.prop_1)) { println(value_1.dec()) println(value_2?.toByte()) - println(o.prop_1.plus(3)) + println(o.prop_1.plus(3)) } if (!contracts.case_6_2(value_1, value_2, o.prop_1, this.prop_1)) { println(value_1.dec()) println(value_2?.toByte()) - println(o.prop_1.plus(3)) + println(o.prop_1.plus(3)) } if (contracts.case_6_3(value_1, value_2, o.prop_1, this.prop_1) == null) { println(value_1.dec()) println(value_2?.toByte()) - println(o.prop_1.plus(3)) + println(o.prop_1.plus(3)) } if (contracts.case_6_4(value_1, value_2, o.prop_1, this.prop_1) != null) { println(value_1.dec()) println(value_2?.toByte()) - println(o.prop_1.plus(3)) + println(o.prop_1.plus(3)) } } } diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/43.fir.kt b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/43.fir.kt index 1b2f19114f8..b0bb7f7457c 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/43.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/43.fir.kt @@ -14,7 +14,7 @@ fun case_1(x: Double?, y: Double?) : Double { } else if (x == null && y != null) { y } else { - x + y + x + y } } diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/fir/FirUtils.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/fir/FirUtils.kt index 0424c83339e..d3d908a66eb 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/fir/FirUtils.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/fir/FirUtils.kt @@ -43,7 +43,7 @@ internal fun FirErrorNamedReference.getCandidateSymbols(): Collection listOf(diagnostic.candidate.symbol) is ConeHiddenCandidateError -> listOf(diagnostic.candidateSymbol) - is ConeAmbiguityError -> diagnostic.candidates + is ConeAmbiguityError -> diagnostic.candidates.map { it.symbol } is ConeOperatorAmbiguityError -> diagnostic.candidates is ConeUnsupportedCallableReferenceTarget -> listOf(diagnostic.fir.symbol) else -> emptyList() diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirReferenceShortener.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirReferenceShortener.kt index ee1b4a427d7..07e0e918ed9 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirReferenceShortener.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirReferenceShortener.kt @@ -383,7 +383,7 @@ private class ElementsToShortenCollector(private val shorteningContext: FirShort private fun getSingleUnambiguousCandidate(namedReference: FirErrorNamedReference): FirCallableSymbol<*>? { val coneAmbiguityError = namedReference.diagnostic as? ConeAmbiguityError ?: return null - val candidates = coneAmbiguityError.candidates.map { it as FirCallableSymbol<*> } + val candidates = coneAmbiguityError.candidates.map { it.symbol as FirCallableSymbol<*> } require(candidates.isNotEmpty()) { "Cannot have zero candidates" } val distinctCandidates = candidates.distinctBy { it.callableId } diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/FirReferenceResolveHelper.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/FirReferenceResolveHelper.kt index a4b7599cfca..9f44feb50ca 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/FirReferenceResolveHelper.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/FirReferenceResolveHelper.kt @@ -15,7 +15,10 @@ import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.psi import org.jetbrains.kotlin.fir.references.* import org.jetbrains.kotlin.fir.resolve.calls.FirSyntheticPropertySymbol -import org.jetbrains.kotlin.fir.resolve.diagnostics.* +import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeAmbiguityError +import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeInapplicableCandidateError +import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeOperatorAmbiguityError +import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnmatchedTypeArgumentsError import org.jetbrains.kotlin.fir.resolve.symbolProvider import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol @@ -284,7 +287,7 @@ internal object FirReferenceResolveHelper { fun getFirSymbolsByErrorNamedReference( errorNamedReference: FirErrorNamedReference, ): Collection> = when (val diagnostic = errorNamedReference.diagnostic) { - is ConeAmbiguityError -> diagnostic.candidates + is ConeAmbiguityError -> diagnostic.candidates.map { it.symbol } is ConeOperatorAmbiguityError -> diagnostic.candidates is ConeInapplicableCandidateError -> listOf(diagnostic.candidate.symbol) else -> emptyList()