diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CandidateFactory.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CandidateFactory.kt index 1edde1117a3..d3939004994 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CandidateFactory.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CandidateFactory.kt @@ -34,10 +34,11 @@ class CandidateFactory( implicitExtensionReceiverValue: ImplicitReceiverValue<*>?, explicitReceiverKind: ExplicitReceiverKind ): Candidate { - return Candidate( + val candidate = Candidate( symbol, dispatchReceiverValue, implicitExtensionReceiverValue, explicitReceiverKind, bodyResolveComponents, baseSystem, callInfo ) + return candidate } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirStandardOverrideChecker.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirStandardOverrideChecker.kt index 9e581068225..4657c3cb79a 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirStandardOverrideChecker.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirStandardOverrideChecker.kt @@ -16,13 +16,38 @@ import org.jetbrains.kotlin.fir.types.ConeTypeContext import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.types.AbstractStrictEqualityTypeChecker.strictEqualTypes +import org.jetbrains.kotlin.types.AbstractTypeChecker +import org.jetbrains.kotlin.types.model.KotlinTypeMarker +import org.jetbrains.kotlin.types.model.SimpleTypeMarker class FirStandardOverrideChecker(session: FirSession) : FirAbstractOverrideChecker() { private val context: ConeTypeContext = session.typeContext - private fun isEqualTypes(candidateType: ConeKotlinType, baseType: ConeKotlinType, substitutor: ConeSubstitutor) = - strictEqualTypes(context, substitutor.substituteOrSelf(candidateType), substitutor.substituteOrSelf(baseType)) + private fun isEqualTypes(candidateType: ConeKotlinType, baseType: ConeKotlinType, substitutor: ConeSubstitutor): Boolean{ + val substitutedCandidateType = substitutor.substituteOrSelf(candidateType) + val substitutedBaseType = substitutor.substituteOrSelf(baseType) + return with(context) { + val baseIsFlexible = substitutedBaseType.isFlexible() + val candidateIsFlexible = substitutedCandidateType.isFlexible() + if (baseIsFlexible == candidateIsFlexible) { + return strictEqualTypes(context, substitutedCandidateType, substitutedBaseType) + } + val lowerBound: SimpleTypeMarker + val upperBound: SimpleTypeMarker + val type: KotlinTypeMarker + if (baseIsFlexible) { + lowerBound = substitutedBaseType.lowerBoundIfFlexible() + upperBound = substitutedBaseType.upperBoundIfFlexible() + type = substitutedCandidateType + } else { + lowerBound = substitutedCandidateType.lowerBoundIfFlexible() + upperBound = substitutedCandidateType.upperBoundIfFlexible() + type = substitutedBaseType + } + AbstractTypeChecker.isSubtypeOf(context, lowerBound, type) && AbstractTypeChecker.isSubtypeOf(context, type, upperBound) + } + } override fun isEqualTypes(candidateTypeRef: FirTypeRef, baseTypeRef: FirTypeRef, substitutor: ConeSubstitutor) = isEqualTypes((candidateTypeRef as FirResolvedTypeRef).type, (baseTypeRef as FirResolvedTypeRef).type, substitutor) diff --git a/compiler/fir/resolve/testData/resolve/arguments/ambiguityOnJavaOverride.kt b/compiler/fir/resolve/testData/resolve/arguments/ambiguityOnJavaOverride.kt new file mode 100644 index 00000000000..13afe98f238 --- /dev/null +++ b/compiler/fir/resolve/testData/resolve/arguments/ambiguityOnJavaOverride.kt @@ -0,0 +1,19 @@ +// FILE: A.java + +public class A { + Object foo(String s) { + return null; + }; +} + +// FILE: main.kt + +class B : A() { + override fun foo(s: String): Any? { + return null + } +} + +fun test(b: B) { + b.foo("") +} \ No newline at end of file diff --git a/compiler/fir/resolve/testData/resolve/arguments/ambiguityOnJavaOverride.txt b/compiler/fir/resolve/testData/resolve/arguments/ambiguityOnJavaOverride.txt new file mode 100644 index 00000000000..927f817f32c --- /dev/null +++ b/compiler/fir/resolve/testData/resolve/arguments/ambiguityOnJavaOverride.txt @@ -0,0 +1,14 @@ +FILE: main.kt + public final class B : R|A| { + public constructor(): R|B| { + super() + } + + public final override fun foo(s: R|kotlin/String|): R|kotlin/Any?| { + ^foo Null(null) + } + + } + public final fun test(b: R|B|): R|kotlin/Unit| { + R|/b|.R|/B.foo|(String()) + } diff --git a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java index fff22064ba2..07ea21ea3fc 100644 --- a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java +++ b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java @@ -230,6 +230,11 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest { KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/fir/resolve/testData/resolve/arguments"), Pattern.compile("^([^.]+)\\.kt$"), true); } + @TestMetadata("ambiguityOnJavaOverride.kt") + public void testAmbiguityOnJavaOverride() throws Exception { + runTest("compiler/fir/resolve/testData/resolve/arguments/ambiguityOnJavaOverride.kt"); + } + @TestMetadata("default.kt") public void testDefault() throws Exception { runTest("compiler/fir/resolve/testData/resolve/arguments/default.kt");