diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevelHandler.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevelHandler.kt index 8b8042e77aa..6c17c315da7 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevelHandler.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevelHandler.kt @@ -5,21 +5,12 @@ package org.jetbrains.kotlin.fir.resolve.calls.tower -import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier import org.jetbrains.kotlin.fir.resolve.calls.* import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.fir.scopes.ProcessorAction import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol -import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol -import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol -import org.jetbrains.kotlin.fir.typeContext -import org.jetbrains.kotlin.fir.types.ConeClassLikeType -import org.jetbrains.kotlin.fir.types.ConeStarProjection -import org.jetbrains.kotlin.fir.types.coneType -import org.jetbrains.kotlin.fir.types.constructClassType import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind -import org.jetbrains.kotlin.types.AbstractTypeChecker internal class CandidateFactoriesAndCollectors( // Common calls @@ -88,31 +79,6 @@ private class TowerScopeLevelProcessor( scope: FirScope, builtInExtensionFunctionReceiverValue: ReceiverValue? ) { - // Check explicit extension receiver for default package members - if (symbol is FirNamedFunctionSymbol && dispatchReceiverValue == null && - extensionReceiverValue != null && - callInfo.explicitReceiver !is FirResolvedQualifier && - symbol.callableId.packageName.startsWith(defaultPackage) - ) { - val extensionReceiverType = extensionReceiverValue.type as? ConeClassLikeType - if (extensionReceiverType != null) { - val declarationReceiverType = (symbol as? FirCallableSymbol<*>)?.fir?.receiverTypeRef?.coneType - if (declarationReceiverType is ConeClassLikeType) { - if (!AbstractTypeChecker.isSubtypeOf( - candidateFactory.context.session.typeContext, - extensionReceiverType, - declarationReceiverType.lookupTag.constructClassType( - declarationReceiverType.typeArguments.map { ConeStarProjection }.toTypedArray(), - isNullable = true - ) - ) - ) { - return - } - } - } - } - // --- resultCollector.consumeCandidate( group, candidateFactory.createCandidate( callInfo, diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevels.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevels.kt index 5912506b72c..37fbc428bad 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevels.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevels.kt @@ -15,12 +15,18 @@ import org.jetbrains.kotlin.fir.resolve.calls.* import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.fir.scopes.ProcessorAction +import org.jetbrains.kotlin.fir.scopes.impl.FirDefaultStarImportingScope import org.jetbrains.kotlin.fir.scopes.impl.importedFromObjectData import org.jetbrains.kotlin.fir.scopes.processClassifiersByName import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol import org.jetbrains.kotlin.fir.symbols.impl.* +import org.jetbrains.kotlin.fir.typeContext import org.jetbrains.kotlin.fir.types.ConeClassLikeType +import org.jetbrains.kotlin.fir.types.ConeStarProjection +import org.jetbrains.kotlin.fir.types.coneType +import org.jetbrains.kotlin.fir.types.constructClassType import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.types.AbstractTypeChecker import org.jetbrains.kotlin.util.OperatorNameConventions abstract class TowerScopeLevel { @@ -178,12 +184,6 @@ class ScopeTowerLevel( private val extensionsOnly: Boolean, private val includeInnerConstructors: Boolean ) : SessionBasedTowerLevel(session) { - private fun FirCallableSymbol<*>.hasConsistentReceivers(extensionReceiver: Receiver?): Boolean = - when { - extensionsOnly && !hasExtensionReceiver() -> false - !hasConsistentExtensionReceiver(extensionReceiver) -> false - else -> true - } private fun dispatchReceiverValue(candidate: FirCallableSymbol<*>): ReceiverValue? { candidate.fir.importedFromObjectData?.let { data -> @@ -215,20 +215,48 @@ class ScopeTowerLevel( } } + private fun shouldSkipCandidateWithInconsistentExtensionReceiver(candidate: FirCallableSymbol<*>): Boolean { + // Pre-check explicit extension receiver for default package top-level members + if (scope is FirDefaultStarImportingScope && extensionReceiver != null) { + val extensionReceiverType = extensionReceiver.type + if (extensionReceiverType is ConeClassLikeType) { + val declarationReceiverType = candidate.fir.receiverTypeRef?.coneType + if (declarationReceiverType is ConeClassLikeType) { + if (!AbstractTypeChecker.isSubtypeOf( + session.typeContext, + extensionReceiverType, + declarationReceiverType.lookupTag.constructClassType( + declarationReceiverType.typeArguments.map { ConeStarProjection }.toTypedArray(), + isNullable = true + ) + ) + ) { + return true + } + } + } + } + return false + } + private fun > consumeCallableCandidate( candidate: FirCallableSymbol<*>, processor: TowerScopeLevelProcessor ) { - if (candidate.hasConsistentReceivers(extensionReceiver)) { - val dispatchReceiverValue = dispatchReceiverValue(candidate) - val unwrappedCandidate = candidate.fir.importedFromObjectData?.original?.symbol ?: candidate - @Suppress("UNCHECKED_CAST") - processor.consumeCandidate( - unwrappedCandidate as T, dispatchReceiverValue, - extensionReceiverValue = extensionReceiver, - scope - ) + val candidateReceiverTypeRef = candidate.fir.receiverTypeRef + val receiverExpected = extensionsOnly || extensionReceiver != null + if (candidateReceiverTypeRef == null == receiverExpected) return + val dispatchReceiverValue = dispatchReceiverValue(candidate) + if (dispatchReceiverValue == null && shouldSkipCandidateWithInconsistentExtensionReceiver(candidate)) { + return } + val unwrappedCandidate = candidate.fir.importedFromObjectData?.original?.symbol ?: candidate + @Suppress("UNCHECKED_CAST") + processor.consumeCandidate( + unwrappedCandidate as T, dispatchReceiverValue, + extensionReceiverValue = extensionReceiver, + scope + ) } override fun processFunctionsByName( diff --git a/compiler/testData/diagnostics/tests/unsignedTypes/callDefaultConstructorOfUnsignedType.fir.kt b/compiler/testData/diagnostics/tests/unsignedTypes/callDefaultConstructorOfUnsignedType.fir.kt index cb8bae9af5b..761b6af164b 100644 --- a/compiler/testData/diagnostics/tests/unsignedTypes/callDefaultConstructorOfUnsignedType.fir.kt +++ b/compiler/testData/diagnostics/tests/unsignedTypes/callDefaultConstructorOfUnsignedType.fir.kt @@ -1 +1 @@ -val foo = UInt() +val foo = UInt() diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineOrdinaryOfCrossinlineOrdinary.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineOrdinaryOfCrossinlineOrdinary.fir.kt index 10b112eae1c..947e56276e4 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineOrdinaryOfCrossinlineOrdinary.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineOrdinaryOfCrossinlineOrdinary.fir.kt @@ -21,7 +21,7 @@ inline fun test(crossinline c: () -> Unit) { } } val l = { c() } - c.startCoroutine(EmptyContinuation) + c.startCoroutine(EmptyContinuation) } suspend fun calculate() = "OK" diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineOrdinaryOfNoinlineOrdinary.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineOrdinaryOfNoinlineOrdinary.fir.kt index 74f94fa1795..405495a2714 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineOrdinaryOfNoinlineOrdinary.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineOrdinaryOfNoinlineOrdinary.fir.kt @@ -20,7 +20,7 @@ inline fun test(noinline c: () -> Unit) { } } val l = { c() } - c.startCoroutine(EmptyContinuation) + c.startCoroutine(EmptyContinuation) } suspend fun calculate() = "OK" diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineOrdinaryOfOrdinary.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineOrdinaryOfOrdinary.fir.kt index 2a6c74bef99..4085e871dd5 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineOrdinaryOfOrdinary.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineOrdinaryOfOrdinary.fir.kt @@ -21,7 +21,7 @@ inline fun test(c: () -> Unit) { } } val l = { c() } - c.startCoroutine(EmptyContinuation) + c.startCoroutine(EmptyContinuation) } fun builder(c: suspend () -> Unit) { diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineSuspendOfCrossinlineOrdinary.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineSuspendOfCrossinlineOrdinary.fir.kt index 3a8b813993b..7dadb75ca42 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineSuspendOfCrossinlineOrdinary.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineSuspendOfCrossinlineOrdinary.fir.kt @@ -20,7 +20,7 @@ suspend inline fun test(crossinline c: () -> Unit) { } } val l = { c() } - c.startCoroutine(EmptyContinuation) + c.startCoroutine(EmptyContinuation) } fun builder(c: suspend () -> Unit) { diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineSuspendOfNoinlineOrdinary.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineSuspendOfNoinlineOrdinary.fir.kt index 65833bc430a..a24f85d9853 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineSuspendOfNoinlineOrdinary.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineSuspendOfNoinlineOrdinary.fir.kt @@ -20,7 +20,7 @@ suspend inline fun test(noinline c: () -> Unit) { } } val l = { c() } - c.startCoroutine(EmptyContinuation) + c.startCoroutine(EmptyContinuation) } fun builder(c: suspend () -> Unit) { diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineSuspendOfOrdinary.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineSuspendOfOrdinary.fir.kt index cfea83085db..c036c55114a 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineSuspendOfOrdinary.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inlineCrossinline/inlineSuspendOfOrdinary.fir.kt @@ -20,7 +20,7 @@ suspend inline fun test(c: () -> Unit) { } } val l = { c() } - c.startCoroutine(EmptyContinuation) + c.startCoroutine(EmptyContinuation) } suspend fun calculate() = "OK" diff --git a/compiler/tests-spec/testData/diagnostics/linked/type-system/type-kinds/built-in-types/kotlin.nothing/p-1/neg/2.1.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/type-system/type-kinds/built-in-types/kotlin.nothing/p-1/neg/2.1.fir.kt index 4417f42a6d7..bbed635db8b 100644 --- a/compiler/tests-spec/testData/diagnostics/linked/type-system/type-kinds/built-in-types/kotlin.nothing/p-1/neg/2.1.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/linked/type-system/type-kinds/built-in-types/kotlin.nothing/p-1/neg/2.1.fir.kt @@ -6,7 +6,7 @@ class Case1(val nothing: Nothing) fun case1() { - val res = Case1(Nothing()) + val res = Case1(Nothing()) } diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/15.fir.kt b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/15.fir.kt index b737b5d437f..f9794f96f88 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/15.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/contracts/analysis/smartcasts/neg/15.fir.kt @@ -30,14 +30,14 @@ import contracts.* // TESTCASE NUMBER: 1 fun case_1(value: Any) { if (contracts.case_1_2(contracts.case_1_1(value is Char))) { - println(value.category) + println(value.category) } } // TESTCASE NUMBER: 2 fun case_2(value: Any) { if (contracts.case_2(value is Char) is Boolean) { - println(value.category) + println(value.category) } } diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/1.fir.kt b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/1.fir.kt index 02adb3416d6..dd25f83a07c 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/1.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/1.fir.kt @@ -263,7 +263,7 @@ fun case_16() { // TESTCASE NUMBER: 17 val case_17 = if (nullableIntProperty == null == true == false) 0 else { nullableIntProperty - nullableIntProperty.java + nullableIntProperty.java } //TESTCASE NUMBER: 18