[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 { private fun isEqualTypes(candidateType: ConeKotlinType, baseType: ConeKotlinType, substitutor: ConeSubstitutor): Boolean {
if (candidateType is ConeFlexibleType) return isEqualTypes(candidateType.lowerBound, baseType, substitutor) if (candidateType is ConeFlexibleType) return isEqualTypes(candidateType.lowerBound, baseType, substitutor)
if (baseType is ConeFlexibleType) return isEqualTypes(candidateType, baseType.lowerBound, substitutor) if (baseType is ConeFlexibleType) return isEqualTypes(candidateType, baseType.lowerBound, substitutor)
return if (candidateType is ConeClassLikeType && baseType is ConeClassLikeType) { if (candidateType is ConeClassLikeType && baseType is ConeClassLikeType) {
candidateType.lookupTag.classId.let { it.readOnlyToMutable() ?: it } == baseType.lookupTag.classId.let { it.readOnlyToMutable() ?: it } return candidateType.lookupTag.classId.let { it.readOnlyToMutable() ?: it } == baseType.lookupTag.classId.let { it.readOnlyToMutable() ?: it }
} else { }
with(context) { if (candidateType is ConeClassLikeType && baseType is ConeTypeParameterType) {
isEqualTypeConstructors( val boundType = baseType.lookupTag.typeParameterSymbol.fir.bounds.singleOrNull()?.toNotNullConeKotlinType(
substitutor.substituteOrSelf(candidateType).typeConstructor(), session, javaTypeParameterStack
substitutor.substituteOrSelf(baseType).typeConstructor() )
) 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) = override fun isEqualTypes(candidateTypeRef: FirTypeRef, baseTypeRef: FirTypeRef, substitutor: ConeSubstitutor) =
+1 -1
View File
@@ -4,7 +4,7 @@ FILE: test.kt
^ String(value) ^ 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)) 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|<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|())) 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?>() val someMap = WeakHashMap<Any?, Any?>()
fun foo() { 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 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 get(): R|java/util/WeakHashMap<kotlin/Any?, kotlin/Any?>|
public final fun foo(): R|kotlin/Unit| { 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 FILE: removeOnAbstractMap.kt
public final fun test(map: R|java/util/AbstractMap<kotlin/String, kotlin/Int>|): R|kotlin/Unit| { 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/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 // KJS_WITH_FULL_RUNTIME
var x = 0 var x = 0
fun inc(): Int { fun inc(): Int {
@@ -18,6 +18,6 @@ fun main(a: A, b: B, c: ArrayList<Int>) {
a.removeAt(0) a.removeAt(0)
b.remove(1) b.remove(1)
b.removeAt(0) b.removeAt(0)
c.<!AMBIGUITY!>remove<!>(1) c.remove(1)
c.removeAt(0) c.removeAt(0)
} }
@@ -14,7 +14,7 @@ fun evaluateArg(expr: CharSequence, numbers: ArrayList<Int>): Int {
if (c >= '0' && c <= '9') { if (c >= '0' && c <= '9') {
val n = c <!UNRESOLVED_REFERENCE!>-<!> '0' val n = c <!UNRESOLVED_REFERENCE!>-<!> '0'
if (!numbers.contains(n)) throw Exception("You used incorrect number: " + n) if (!numbers.contains(n)) throw Exception("You used incorrect number: " + n)
numbers.<!AMBIGUITY!>remove<!>(n) numbers.remove(n)
return n return n
} }
throw Exception("Syntax error: Unrecognized character " + c) throw Exception("Syntax error: Unrecognized character " + c)
@@ -39,9 +39,9 @@ fun test2(value: Any?) {
// From KT-32116 // From KT-32116
fun test3(h: HashMap<*, *>) { fun test3(h: HashMap<*, *>) {
val a = <!AMBIGUITY!>h["str"]<!> val a = h["str"]
val b = <!AMBIGUITY!>h[1]<!> val b = h[1]
val c = <!AMBIGUITY!>h["other"]<!> as? Double val c = h["other"] as? Double
} }
// From KT-32218 // From KT-32218