FIR: Support flexible types in getErasedVersionOfFirstUpperBound
This commit is contained in:
@@ -182,7 +182,7 @@ private fun FirTypeParameter.getErasedUpperBound(
|
||||
return getErasedVersionOfFirstUpperBound(firstUpperBound, mutableSetOf(this, potentiallyRecursiveTypeParameter), defaultValue)
|
||||
}
|
||||
|
||||
private tailrec fun getErasedVersionOfFirstUpperBound(
|
||||
private fun getErasedVersionOfFirstUpperBound(
|
||||
firstUpperBound: ConeKotlinType,
|
||||
alreadyVisitedParameters: MutableSet<FirTypeParameter?>,
|
||||
defaultValue: () -> ConeKotlinType
|
||||
@@ -191,6 +191,23 @@ private tailrec fun getErasedVersionOfFirstUpperBound(
|
||||
is ConeClassLikeType ->
|
||||
firstUpperBound.withArguments(firstUpperBound.typeArguments.map { ConeStarProjection }.toTypedArray())
|
||||
|
||||
is ConeFlexibleType -> {
|
||||
val lowerBound =
|
||||
getErasedVersionOfFirstUpperBound(firstUpperBound.lowerBound, alreadyVisitedParameters, defaultValue)
|
||||
.lowerBoundIfFlexible()
|
||||
if (firstUpperBound.upperBound is ConeTypeParameterType) {
|
||||
// Avoid exponential complexity
|
||||
ConeFlexibleType(
|
||||
lowerBound,
|
||||
lowerBound.withNullability(ConeNullability.NULLABLE)
|
||||
)
|
||||
} else {
|
||||
ConeFlexibleType(
|
||||
lowerBound,
|
||||
getErasedVersionOfFirstUpperBound(firstUpperBound.upperBound, alreadyVisitedParameters, defaultValue)
|
||||
)
|
||||
}
|
||||
}
|
||||
is ConeTypeParameterType -> {
|
||||
val current = firstUpperBound.lookupTag.typeParameterSymbol.fir
|
||||
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ val strList: List<String> = null!!
|
||||
fun main() {
|
||||
val rawA = Test.rawAField
|
||||
rawA.first = Test.rawAField.second
|
||||
Test.rawAField.second = rawA.first.<!INAPPLICABLE_CANDIDATE!>second<!>
|
||||
Test.rawAField.second = rawA.first.second
|
||||
|
||||
rawA.listOfDoubles = strList
|
||||
rawA.listOfDoubles = "" // first should be List
|
||||
|
||||
+3
-3
@@ -27,12 +27,12 @@ public class Test {
|
||||
|
||||
fun foo(x: B<*>) {
|
||||
// TODO: x.foo() now is flexible type instead of raw, because of captured type approximation
|
||||
val q: MutableList<String> = x.foo().<!INAPPLICABLE_CANDIDATE!>getChildrenStubs<!>()
|
||||
val q: MutableList<String> = x.foo().getChildrenStubs()
|
||||
|
||||
// Raw(B).field erased to A<Any!>..A<out Any!>?
|
||||
Test.rawB.field = A<String>()
|
||||
val anyA: A<Any> = Test.rawB.field
|
||||
|
||||
Test.rawB.field.<!INAPPLICABLE_CANDIDATE!>consume<!>("")
|
||||
val y: Any = Test.rawB.field.<!INAPPLICABLE_CANDIDATE!>produce<!>()
|
||||
Test.rawB.field.consume("")
|
||||
val y: Any = Test.rawB.field.produce()
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
public final class ClassWithTypePP<P, Q : R|P?|> : R|kotlin/Any| {
|
||||
public constructor<P, Q : R|P?|>(): R|test/ClassWithTypePP<P, Q>|
|
||||
public final class ClassWithTypePP<P, Q : R|ft<P, P?>!|> : R|kotlin/Any| {
|
||||
public constructor<P, Q : R|ft<P, P?>!|>(): R|test/ClassWithTypePP<P, Q>|
|
||||
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
public open class ClassWithTypePRefNext<R : R|kotlin/collections/MutableIterable<P>?|, P> : R|kotlin/Any| {
|
||||
public constructor<R : R|kotlin/collections/MutableIterable<P>?|, P>(): R|test/ClassWithTypePRefNext<R, P>|
|
||||
public open class ClassWithTypePRefNext<R : R|ft<kotlin/collections/MutableIterable<P>, kotlin/collections/MutableIterable<P>?>!|, P> : R|kotlin/Any| {
|
||||
public constructor<R : R|ft<kotlin/collections/MutableIterable<P>, kotlin/collections/MutableIterable<P>?>!|, P>(): R|test/ClassWithTypePRefNext<R, P>|
|
||||
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
public final class ClassWithTypePRefSelf<P : R|kotlin/Enum<P>?|> : R|kotlin/Any| {
|
||||
public constructor<P : R|kotlin/Enum<P>?|>(): R|test/ClassWithTypePRefSelf<P>|
|
||||
public final class ClassWithTypePRefSelf<P : R|ft<kotlin/Enum<P>, kotlin/Enum<P>?>!|> : R|kotlin/Any| {
|
||||
public constructor<P : R|ft<kotlin/Enum<P>, kotlin/Enum<P>?>!|>(): R|test/ClassWithTypePRefSelf<P>|
|
||||
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
public final class ClassWithTypePRefSelfAndClass<P : R|test/ClassWithTypePRefSelfAndClass<P>?|> : R|kotlin/Any| {
|
||||
public constructor<P : R|test/ClassWithTypePRefSelfAndClass<P>?|>(): R|test/ClassWithTypePRefSelfAndClass<P>|
|
||||
public final class ClassWithTypePRefSelfAndClass<P : R|ft<test/ClassWithTypePRefSelfAndClass<P>, test/ClassWithTypePRefSelfAndClass<P>?>!|> : R|kotlin/Any| {
|
||||
public constructor<P : R|ft<test/ClassWithTypePRefSelfAndClass<P>, test/ClassWithTypePRefSelfAndClass<P>?>!|>(): R|test/ClassWithTypePRefSelfAndClass<P>|
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
public open class MethodTypePOneUpperBound : R|kotlin/Any| {
|
||||
public open operator fun <T : R|kotlin/Cloneable?|> bar(): R|kotlin/Unit|
|
||||
public open operator fun <T : R|ft<kotlin/Cloneable, kotlin/Cloneable?>!|> bar(): R|kotlin/Unit|
|
||||
|
||||
public constructor(): R|test/MethodTypePOneUpperBound|
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
public open class MethodTypePTwoUpperBounds : R|kotlin/Any| {
|
||||
public open operator fun <T : R|kotlin/Cloneable?|, R|java/lang/Runnable?|> foo(): R|kotlin/Unit|
|
||||
public open operator fun <T : R|ft<kotlin/Cloneable, kotlin/Cloneable?>!|, R|ft<java/lang/Runnable, java/lang/Runnable?>!|> foo(): R|kotlin/Unit|
|
||||
|
||||
public constructor(): R|test/MethodTypePTwoUpperBounds|
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
public final class MethodWithTypePP : R|kotlin/Any| {
|
||||
public final operator fun <P, Q : R|P?|> f(): R|kotlin/Unit|
|
||||
public final operator fun <P, Q : R|ft<P, P?>!|> f(): R|kotlin/Unit|
|
||||
|
||||
public constructor(): R|test/MethodWithTypePP|
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
public open class MethodWithTypePRefClassP<P> : R|kotlin/Any| {
|
||||
public final operator fun <Q : R|P?|> f(): R|kotlin/Unit|
|
||||
public final operator fun <Q : R|ft<P, P?>!|> f(): R|kotlin/Unit|
|
||||
|
||||
public constructor<P>(): R|test/MethodWithTypePRefClassP<P>|
|
||||
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
public abstract interface RawUpperBound<T : R|test/RawUpperBound<*>?|> : R|kotlin/Any| {
|
||||
public abstract interface RawUpperBound<T : R|ft<test/RawUpperBound<*>, test/RawUpperBound<*>?>!|> : R|kotlin/Any| {
|
||||
}
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
public abstract interface RecursiveRawUpperBound<T : R|test/RecursiveRawUpperBound<*>?|> : R|kotlin/Any| {
|
||||
public abstract interface RecursiveRawUpperBound<T : R|ft<test/RecursiveRawUpperBound<*>, test/RecursiveRawUpperBound<*>?>!|> : R|kotlin/Any| {
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,2 +1,2 @@
|
||||
public abstract interface RecursiveWildcardUpperBound<T : R|test/RecursiveWildcardUpperBound<*>?|> : R|kotlin/Any| {
|
||||
public abstract interface RecursiveWildcardUpperBound<T : R|ft<test/RecursiveWildcardUpperBound<*>, test/RecursiveWildcardUpperBound<*>?>!|> : R|kotlin/Any| {
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
public open class ConstructorGenericUpperBound : R|kotlin/Any| {
|
||||
public constructor<P : R|java/util/RandomAccess?|>(p: R|ft<P, P?>!|): R|test/ConstructorGenericUpperBound|
|
||||
public constructor<P : R|ft<java/util/RandomAccess, java/util/RandomAccess?>!|>(p: R|ft<P, P?>!|): R|test/ConstructorGenericUpperBound|
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
public open class AllBoundsInWhen : R|kotlin/Any| {
|
||||
public open operator fun <T : R|java/io/Serializable?|> foo(): R|kotlin/Unit|
|
||||
public open operator fun <T : R|ft<java/io/Serializable, java/io/Serializable?>!|> foo(): R|kotlin/Unit|
|
||||
|
||||
public constructor(): R|test/AllBoundsInWhen|
|
||||
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
public open class MethodWithTypeParameters : R|kotlin/Any| {
|
||||
public open operator fun <A, B : R|java/lang/Runnable?|, R|kotlin/collections/MutableList<kotlin/Cloneable>?|> foo(a: R|ft<A, A?>!|, b: R|ft<kotlin/collections/MutableList<out B>, kotlin/collections/List<out B>?>!|, list: R|ft<kotlin/collections/MutableList<in kotlin/String>, kotlin/collections/List<in kotlin/String>?>!|): R|kotlin/Unit|
|
||||
public open operator fun <A, B : R|ft<java/lang/Runnable, java/lang/Runnable?>!|, R|ft<kotlin/collections/MutableList<kotlin/Cloneable>, kotlin/collections/MutableList<kotlin/Cloneable>?>!|> foo(a: R|ft<A, A?>!|, b: R|ft<kotlin/collections/MutableList<out B>, kotlin/collections/List<out B>?>!|, list: R|ft<kotlin/collections/MutableList<in kotlin/String>, kotlin/collections/List<in kotlin/String>?>!|): R|kotlin/Unit|
|
||||
|
||||
public constructor(): R|test/MethodWithTypeParameters|
|
||||
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
public open class WrongTypeParameterBoundStructure1 : R|kotlin/Any| {
|
||||
public open operator fun <A, B : R|java/lang/Runnable?|, R|kotlin/collections/MutableList<kotlin/Cloneable>?|> foo(a: R|ft<A, A?>!|, b: R|ft<kotlin/collections/MutableList<out B>, kotlin/collections/List<out B>?>!|): R|kotlin/Unit|
|
||||
public open operator fun <A, B : R|ft<java/lang/Runnable, java/lang/Runnable?>!|, R|ft<kotlin/collections/MutableList<kotlin/Cloneable>, kotlin/collections/MutableList<kotlin/Cloneable>?>!|> foo(a: R|ft<A, A?>!|, b: R|ft<kotlin/collections/MutableList<out B>, kotlin/collections/List<out B>?>!|): R|kotlin/Unit|
|
||||
|
||||
public constructor(): R|test/WrongTypeParameterBoundStructure1|
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
public open class Max : R|kotlin/Any| {
|
||||
public open operator fun <T : R|kotlin/Comparable<in T>?|> max(coll: R|ft<kotlin/collections/MutableCollection<out T>, kotlin/collections/Collection<out T>?>!|): R|ft<T, T?>!|
|
||||
public open operator fun <T : R|ft<kotlin/Any, kotlin/Any?>!|, R|ft<kotlin/Comparable<in T>, kotlin/Comparable<in T>?>!|> max(coll: R|ft<kotlin/collections/MutableCollection<out T>, kotlin/collections/Collection<out T>?>!|): R|ft<T, T?>!|
|
||||
|
||||
public constructor(): R|test/Max|
|
||||
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
public abstract interface GenericInterfaceParameterWithSelfBound<T : R|test/GenericInterfaceParameterWithSelfBound<T>?|> : R|kotlin/Any| {
|
||||
public abstract interface GenericInterfaceParameterWithSelfBound<T : R|ft<test/GenericInterfaceParameterWithSelfBound<T>, test/GenericInterfaceParameterWithSelfBound<T>?>!|> : R|kotlin/Any| {
|
||||
public abstract operator fun method(t: R|ft<T, T?>!|): R|ft<T, T?>!|
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
public abstract interface GenericInterfaceParametersWithBounds<A : R|kotlin/Comparable<A>?|, R|kotlin/Cloneable?|, B : R|kotlin/collections/MutableList<A>?|> : R|kotlin/Any| {
|
||||
public abstract interface GenericInterfaceParametersWithBounds<A : R|ft<kotlin/Comparable<A>, kotlin/Comparable<A>?>!|, R|ft<kotlin/Cloneable, kotlin/Cloneable?>!|, B : R|ft<kotlin/collections/MutableList<A>, kotlin/collections/MutableList<A>?>!|> : R|kotlin/Any| {
|
||||
public abstract operator fun method(a: R|ft<kotlin/Array<ft<A, A?>!>, kotlin/Array<out ft<A, A?>!>?>!|, b: R|ft<B, B?>!|): R|kotlin/Unit|
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
public abstract interface GenericMethodParameters : R|kotlin/Any| {
|
||||
public abstract operator fun <A : R|kotlin/CharSequence?|, B : R|kotlin/collections/MutableList<A>?|> method(a: R|ft<kotlin/Array<ft<A, A?>!>, kotlin/Array<out ft<A, A?>!>?>!|, b: R|ft<B, B?>!|): R|kotlin/Unit|
|
||||
public abstract operator fun <A : R|ft<kotlin/CharSequence, kotlin/CharSequence?>!|, B : R|ft<kotlin/collections/MutableList<A>, kotlin/collections/MutableList<A>?>!|> method(a: R|ft<kotlin/Array<ft<A, A?>!>, kotlin/Array<out ft<A, A?>!>?>!|, b: R|ft<B, B?>!|): R|kotlin/Unit|
|
||||
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
public open class TypeParameterOfMethod : R|kotlin/Any| {
|
||||
public open static operator fun <T> max(comparator: R|ft<java/util/Comparator<ft<T, T?>!>, java/util/Comparator<ft<T, T?>!>?>!|, value1: R|ft<T, T?>!|, value2: R|ft<T, T?>!|): R|ft<T, T?>!|
|
||||
|
||||
public open static operator fun <T : R|kotlin/CharSequence?|> max2(comparator: R|ft<java/util/Comparator<ft<T, T?>!>, java/util/Comparator<ft<T, T?>!>?>!|, value1: R|ft<T, T?>!|, value2: R|ft<T, T?>!|): R|ft<T, T?>!|
|
||||
public open static operator fun <T : R|ft<kotlin/CharSequence, kotlin/CharSequence?>!|> max2(comparator: R|ft<java/util/Comparator<ft<T, T?>!>, java/util/Comparator<ft<T, T?>!>?>!|, value1: R|ft<T, T?>!|, value2: R|ft<T, T?>!|): R|ft<T, T?>!|
|
||||
|
||||
public open static operator fun <A : R|kotlin/CharSequence?|, B : R|kotlin/collections/MutableList<A>?|> method(a: R|ft<java/util/Comparator<ft<A, A?>!>, java/util/Comparator<ft<A, A?>!>?>!|, b: R|ft<B, B?>!|): R|kotlin/Unit|
|
||||
public open static operator fun <A : R|ft<kotlin/CharSequence, kotlin/CharSequence?>!|, B : R|ft<kotlin/collections/MutableList<A>, kotlin/collections/MutableList<A>?>!|> method(a: R|ft<java/util/Comparator<ft<A, A?>!>, java/util/Comparator<ft<A, A?>!>?>!|, b: R|ft<B, B?>!|): R|kotlin/Unit|
|
||||
|
||||
public constructor(): R|test/TypeParameterOfMethod|
|
||||
|
||||
|
||||
Reference in New Issue
Block a user