[FIR] Fix Java override ambiguity (Kotlin type parameter VS Java Object)

This commit is contained in:
Mikhail Glukhikh
2020-02-07 17:01:10 +03:00
parent 4b5f3b7a94
commit dc7621a112
9 changed files with 24 additions and 18 deletions
@@ -28,16 +28,23 @@ class JavaOverrideChecker internal constructor(
private fun isEqualTypes(candidateType: ConeKotlinType, baseType: ConeKotlinType, substitutor: ConeSubstitutor): Boolean {
if (candidateType is ConeFlexibleType) return isEqualTypes(candidateType.lowerBound, baseType, substitutor)
if (baseType is ConeFlexibleType) return isEqualTypes(candidateType, baseType.lowerBound, substitutor)
return if (candidateType is ConeClassLikeType && baseType is ConeClassLikeType) {
candidateType.lookupTag.classId.let { it.readOnlyToMutable() ?: it } == baseType.lookupTag.classId.let { it.readOnlyToMutable() ?: it }
} else {
with(context) {
isEqualTypeConstructors(
substitutor.substituteOrSelf(candidateType).typeConstructor(),
substitutor.substituteOrSelf(baseType).typeConstructor()
)
if (candidateType is ConeClassLikeType && baseType is ConeClassLikeType) {
return candidateType.lookupTag.classId.let { it.readOnlyToMutable() ?: it } == baseType.lookupTag.classId.let { it.readOnlyToMutable() ?: it }
}
if (candidateType is ConeClassLikeType && baseType is ConeTypeParameterType) {
val boundType = baseType.lookupTag.typeParameterSymbol.fir.bounds.singleOrNull()?.toNotNullConeKotlinType(
session, javaTypeParameterStack
)
if (boundType != null) {
return isEqualTypes(candidateType, boundType, substitutor)
}
}
return with(context) {
isEqualTypeConstructors(
substitutor.substituteOrSelf(candidateType).typeConstructor(),
substitutor.substituteOrSelf(baseType).typeConstructor()
)
}
}
override fun isEqualTypes(candidateTypeRef: FirTypeRef, baseTypeRef: FirTypeRef, substitutor: ConeSubstitutor) =
+1 -1
View File
@@ -4,7 +4,7 @@ FILE: test.kt
^ String(value)
}
)
lval otherResult: R|ft<kotlin/String, kotlin/String?>!| = R|<local>/map|.R|FakeOverride<kotlin/collections/Map.getOrDefault: R|ft<kotlin/String, kotlin/String?>!|>|(String(key), String(value))
lval otherResult: R|ft<kotlin/String, kotlin/String?>!| = R|<local>/map|.R|FakeOverride<java/util/Map.getOrDefault: R|ft<kotlin/String, kotlin/String?>!|>|(String(key), String(value))
lval anotherResult: R|kotlin/String?| = R|<local>/map|.R|FakeOverride<java/util/Map.replace: R|kotlin/String?|>|(String(key), String(value))
R|<local>/map|.R|FakeOverride<java/util/Map.forEach: R|kotlin/Unit|>|(<L> = forEach@fun <anonymous>(key: R|ft<kotlin/String, kotlin/String?>!|, value: R|ft<kotlin/String, kotlin/String?>!|): R|kotlin/Unit| {
R|kotlin/io/println|(<strcat>(R|<local>/key|.R|kotlin/Any.toString|(), String(: ), R|<local>/value|.R|kotlin/Any.toString|()))
@@ -5,6 +5,6 @@ import java.util.*
val someMap = WeakHashMap<Any?, Any?>()
fun foo() {
<!AMBIGUITY!>someMap[""]<!>
someMap[""]
}
@@ -2,5 +2,5 @@ FILE: weakHashMap.kt
public final val someMap: R|java/util/WeakHashMap<kotlin/Any?, kotlin/Any?>| = R|java/util/WeakHashMap.WeakHashMap|<R|kotlin/Any?|, R|kotlin/Any?|>()
public get(): R|java/util/WeakHashMap<kotlin/Any?, kotlin/Any?>|
public final fun foo(): R|kotlin/Unit| {
R|/someMap|.<Ambiguity: get, [java/util/WeakHashMap.get, kotlin/collections/Map.get]>#(String())
R|/someMap|.R|FakeOverride<java/util/WeakHashMap.get: R|kotlin/Any?|>|(String())
}
@@ -1,5 +1,5 @@
FILE: removeOnAbstractMap.kt
public final fun test(map: R|java/util/AbstractMap<kotlin/String, kotlin/Int>|): R|kotlin/Unit| {
R|<local>/map|.R|FakeOverride<kotlin/collections/MutableMap.remove: R|kotlin/Boolean|>|(String(), Null(null))
R|<local>/map|.R|FakeOverride<kotlin/collections/MutableMap.remove: R|kotlin/Int?|>|(Null(null))
R|<local>/map|.R|FakeOverride<java/util/AbstractMap.remove: R|kotlin/Int?|>|(Null(null))
}
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// KJS_WITH_FULL_RUNTIME
var x = 0
fun inc(): Int {
@@ -18,6 +18,6 @@ fun main(a: A, b: B, c: ArrayList<Int>) {
a.removeAt(0)
b.remove(1)
b.removeAt(0)
c.<!AMBIGUITY!>remove<!>(1)
c.remove(1)
c.removeAt(0)
}
@@ -14,7 +14,7 @@ fun evaluateArg(expr: CharSequence, numbers: ArrayList<Int>): Int {
if (c >= '0' && c <= '9') {
val n = c <!UNRESOLVED_REFERENCE!>-<!> '0'
if (!numbers.contains(n)) throw Exception("You used incorrect number: " + n)
numbers.<!AMBIGUITY!>remove<!>(n)
numbers.remove(n)
return n
}
throw Exception("Syntax error: Unrecognized character " + c)
@@ -39,9 +39,9 @@ fun test2(value: Any?) {
// From KT-32116
fun test3(h: HashMap<*, *>) {
val a = <!AMBIGUITY!>h["str"]<!>
val b = <!AMBIGUITY!>h[1]<!>
val c = <!AMBIGUITY!>h["other"]<!> as? Double
val a = h["str"]
val b = h[1]
val c = h["other"] as? Double
}
// From KT-32218