[FIR] Fix binding overrides with flexible types in arguments
This commit is contained in:
@@ -34,10 +34,11 @@ class CandidateFactory(
|
|||||||
implicitExtensionReceiverValue: ImplicitReceiverValue<*>?,
|
implicitExtensionReceiverValue: ImplicitReceiverValue<*>?,
|
||||||
explicitReceiverKind: ExplicitReceiverKind
|
explicitReceiverKind: ExplicitReceiverKind
|
||||||
): Candidate {
|
): Candidate {
|
||||||
return Candidate(
|
val candidate = Candidate(
|
||||||
symbol, dispatchReceiverValue, implicitExtensionReceiverValue,
|
symbol, dispatchReceiverValue, implicitExtensionReceiverValue,
|
||||||
explicitReceiverKind, bodyResolveComponents, baseSystem, callInfo
|
explicitReceiverKind, bodyResolveComponents, baseSystem, callInfo
|
||||||
)
|
)
|
||||||
|
return candidate
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+27
-2
@@ -16,13 +16,38 @@ import org.jetbrains.kotlin.fir.types.ConeTypeContext
|
|||||||
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
|
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
|
||||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||||
import org.jetbrains.kotlin.types.AbstractStrictEqualityTypeChecker.strictEqualTypes
|
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() {
|
class FirStandardOverrideChecker(session: FirSession) : FirAbstractOverrideChecker() {
|
||||||
|
|
||||||
private val context: ConeTypeContext = session.typeContext
|
private val context: ConeTypeContext = session.typeContext
|
||||||
|
|
||||||
private fun isEqualTypes(candidateType: ConeKotlinType, baseType: ConeKotlinType, substitutor: ConeSubstitutor) =
|
private fun isEqualTypes(candidateType: ConeKotlinType, baseType: ConeKotlinType, substitutor: ConeSubstitutor): Boolean{
|
||||||
strictEqualTypes(context, substitutor.substituteOrSelf(candidateType), substitutor.substituteOrSelf(baseType))
|
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) =
|
override fun isEqualTypes(candidateTypeRef: FirTypeRef, baseTypeRef: FirTypeRef, substitutor: ConeSubstitutor) =
|
||||||
isEqualTypes((candidateTypeRef as FirResolvedTypeRef).type, (baseTypeRef as FirResolvedTypeRef).type, substitutor)
|
isEqualTypes((candidateTypeRef as FirResolvedTypeRef).type, (baseTypeRef as FirResolvedTypeRef).type, substitutor)
|
||||||
|
|||||||
@@ -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("")
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
FILE: main.kt
|
||||||
|
public final class B : R|A| {
|
||||||
|
public constructor(): R|B| {
|
||||||
|
super<R|A|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
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|<local>/b|.R|/B.foo|(String())
|
||||||
|
}
|
||||||
+5
@@ -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);
|
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")
|
@TestMetadata("default.kt")
|
||||||
public void testDefault() throws Exception {
|
public void testDefault() throws Exception {
|
||||||
runTest("compiler/fir/resolve/testData/resolve/arguments/default.kt");
|
runTest("compiler/fir/resolve/testData/resolve/arguments/default.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user