diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/javaTypeUtils.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/javaTypeUtils.kt index b787283bb44..0fba96fe3e6 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/javaTypeUtils.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/javaTypeUtils.kt @@ -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, 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 diff --git a/compiler/testData/diagnostics/tests/platformTypes/rawTypes/nonTrivialErasure.fir.kt b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/nonTrivialErasure.fir.kt index eab6503afe8..b9ee17efd61 100644 --- a/compiler/testData/diagnostics/tests/platformTypes/rawTypes/nonTrivialErasure.fir.kt +++ b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/nonTrivialErasure.fir.kt @@ -22,7 +22,7 @@ val strList: List = null!! fun main() { val rawA = Test.rawAField rawA.first = Test.rawAField.second - Test.rawAField.second = rawA.first.second + Test.rawAField.second = rawA.first.second rawA.listOfDoubles = strList rawA.listOfDoubles = "" // first should be List diff --git a/compiler/testData/diagnostics/tests/platformTypes/rawTypes/rawTypeInUpperBound.fir.kt b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/rawTypeInUpperBound.fir.kt index fa657b30e10..a5a839b461a 100644 --- a/compiler/testData/diagnostics/tests/platformTypes/rawTypes/rawTypeInUpperBound.fir.kt +++ b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/rawTypeInUpperBound.fir.kt @@ -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 = x.foo().getChildrenStubs() + val q: MutableList = x.foo().getChildrenStubs() // Raw(B).field erased to A..A? Test.rawB.field = A() val anyA: A = Test.rawB.field - Test.rawB.field.consume("") - val y: Any = Test.rawB.field.produce() + Test.rawB.field.consume("") + val y: Any = Test.rawB.field.produce() } diff --git a/compiler/testData/loadJava/compiledJava/ClassWithTypePP.fir.txt b/compiler/testData/loadJava/compiledJava/ClassWithTypePP.fir.txt index 15ed3657b96..8d0dcce66c5 100644 --- a/compiler/testData/loadJava/compiledJava/ClassWithTypePP.fir.txt +++ b/compiler/testData/loadJava/compiledJava/ClassWithTypePP.fir.txt @@ -1,4 +1,4 @@ -public final class ClassWithTypePP : R|kotlin/Any| { - public constructor(): R|test/ClassWithTypePP| +public final class ClassWithTypePP!|> : R|kotlin/Any| { + public constructor!|>(): R|test/ClassWithTypePP| } diff --git a/compiler/testData/loadJava/compiledJava/ClassWithTypePRefNext.fir.txt b/compiler/testData/loadJava/compiledJava/ClassWithTypePRefNext.fir.txt index fe457de72a8..dce3f8b3100 100644 --- a/compiler/testData/loadJava/compiledJava/ClassWithTypePRefNext.fir.txt +++ b/compiler/testData/loadJava/compiledJava/ClassWithTypePRefNext.fir.txt @@ -1,4 +1,4 @@ -public open class ClassWithTypePRefNext?|, P> : R|kotlin/Any| { - public constructor?|, P>(): R|test/ClassWithTypePRefNext| +public open class ClassWithTypePRefNext, kotlin/collections/MutableIterable

?>!|, P> : R|kotlin/Any| { + public constructor, kotlin/collections/MutableIterable

?>!|, P>(): R|test/ClassWithTypePRefNext| } diff --git a/compiler/testData/loadJava/compiledJava/ClassWithTypePRefSelf.fir.txt b/compiler/testData/loadJava/compiledJava/ClassWithTypePRefSelf.fir.txt index 7eeb04402d4..ecf087ad28d 100644 --- a/compiler/testData/loadJava/compiledJava/ClassWithTypePRefSelf.fir.txt +++ b/compiler/testData/loadJava/compiledJava/ClassWithTypePRefSelf.fir.txt @@ -1,4 +1,4 @@ -public final class ClassWithTypePRefSelf

?|> : R|kotlin/Any| { - public constructor

?|>(): R|test/ClassWithTypePRefSelf

| +public final class ClassWithTypePRefSelf

, kotlin/Enum

?>!|> : R|kotlin/Any| { + public constructor

, kotlin/Enum

?>!|>(): R|test/ClassWithTypePRefSelf

| } diff --git a/compiler/testData/loadJava/compiledJava/ClassWithTypePRefSelfAndClass.fir.txt b/compiler/testData/loadJava/compiledJava/ClassWithTypePRefSelfAndClass.fir.txt index 9ca97119335..3bceb76953f 100644 --- a/compiler/testData/loadJava/compiledJava/ClassWithTypePRefSelfAndClass.fir.txt +++ b/compiler/testData/loadJava/compiledJava/ClassWithTypePRefSelfAndClass.fir.txt @@ -1,4 +1,4 @@ -public final class ClassWithTypePRefSelfAndClass

?|> : R|kotlin/Any| { - public constructor

?|>(): R|test/ClassWithTypePRefSelfAndClass

| +public final class ClassWithTypePRefSelfAndClass

, test/ClassWithTypePRefSelfAndClass

?>!|> : R|kotlin/Any| { + public constructor

, test/ClassWithTypePRefSelfAndClass

?>!|>(): R|test/ClassWithTypePRefSelfAndClass

| } diff --git a/compiler/testData/loadJava/compiledJava/MethodTypePOneUpperBound.fir.txt b/compiler/testData/loadJava/compiledJava/MethodTypePOneUpperBound.fir.txt index dc5f00f442e..3f2a0b61a96 100644 --- a/compiler/testData/loadJava/compiledJava/MethodTypePOneUpperBound.fir.txt +++ b/compiler/testData/loadJava/compiledJava/MethodTypePOneUpperBound.fir.txt @@ -1,5 +1,5 @@ public open class MethodTypePOneUpperBound : R|kotlin/Any| { - public open operator fun bar(): R|kotlin/Unit| + public open operator fun !|> bar(): R|kotlin/Unit| public constructor(): R|test/MethodTypePOneUpperBound| diff --git a/compiler/testData/loadJava/compiledJava/MethodTypePTwoUpperBounds.fir.txt b/compiler/testData/loadJava/compiledJava/MethodTypePTwoUpperBounds.fir.txt index 6a47cf7d958..03b4674ba2c 100644 --- a/compiler/testData/loadJava/compiledJava/MethodTypePTwoUpperBounds.fir.txt +++ b/compiler/testData/loadJava/compiledJava/MethodTypePTwoUpperBounds.fir.txt @@ -1,5 +1,5 @@ public open class MethodTypePTwoUpperBounds : R|kotlin/Any| { - public open operator fun foo(): R|kotlin/Unit| + public open operator fun !|, R|ft!|> foo(): R|kotlin/Unit| public constructor(): R|test/MethodTypePTwoUpperBounds| diff --git a/compiler/testData/loadJava/compiledJava/MethodWithTypePP.fir.txt b/compiler/testData/loadJava/compiledJava/MethodWithTypePP.fir.txt index db2b86e8f08..224a8b960c3 100644 --- a/compiler/testData/loadJava/compiledJava/MethodWithTypePP.fir.txt +++ b/compiler/testData/loadJava/compiledJava/MethodWithTypePP.fir.txt @@ -1,5 +1,5 @@ public final class MethodWithTypePP : R|kotlin/Any| { - public final operator fun f(): R|kotlin/Unit| + public final operator fun !|> f(): R|kotlin/Unit| public constructor(): R|test/MethodWithTypePP| diff --git a/compiler/testData/loadJava/compiledJava/MethodWithTypePRefClassP.fir.txt b/compiler/testData/loadJava/compiledJava/MethodWithTypePRefClassP.fir.txt index a359b727382..8ace9ba6fe4 100644 --- a/compiler/testData/loadJava/compiledJava/MethodWithTypePRefClassP.fir.txt +++ b/compiler/testData/loadJava/compiledJava/MethodWithTypePRefClassP.fir.txt @@ -1,5 +1,5 @@ public open class MethodWithTypePRefClassP

: R|kotlin/Any| { - public final operator fun f(): R|kotlin/Unit| + public final operator fun !|> f(): R|kotlin/Unit| public constructor

(): R|test/MethodWithTypePRefClassP

| diff --git a/compiler/testData/loadJava/compiledJava/RawUpperBound.fir.txt b/compiler/testData/loadJava/compiledJava/RawUpperBound.fir.txt index 17f6b19a2dd..ca9b92db9a7 100644 --- a/compiler/testData/loadJava/compiledJava/RawUpperBound.fir.txt +++ b/compiler/testData/loadJava/compiledJava/RawUpperBound.fir.txt @@ -1,2 +1,2 @@ -public abstract interface RawUpperBound?|> : R|kotlin/Any| { +public abstract interface RawUpperBound, test/RawUpperBound<*>?>!|> : R|kotlin/Any| { } diff --git a/compiler/testData/loadJava/compiledJava/RecursiveRawUpperBound.fir.txt b/compiler/testData/loadJava/compiledJava/RecursiveRawUpperBound.fir.txt index 84d2145318e..19cdc5c183c 100644 --- a/compiler/testData/loadJava/compiledJava/RecursiveRawUpperBound.fir.txt +++ b/compiler/testData/loadJava/compiledJava/RecursiveRawUpperBound.fir.txt @@ -1,2 +1,2 @@ -public abstract interface RecursiveRawUpperBound?|> : R|kotlin/Any| { +public abstract interface RecursiveRawUpperBound, test/RecursiveRawUpperBound<*>?>!|> : R|kotlin/Any| { } diff --git a/compiler/testData/loadJava/compiledJava/RecursiveWildcardUpperBound.fir.txt b/compiler/testData/loadJava/compiledJava/RecursiveWildcardUpperBound.fir.txt index ea2b10bbe08..f2593105273 100644 --- a/compiler/testData/loadJava/compiledJava/RecursiveWildcardUpperBound.fir.txt +++ b/compiler/testData/loadJava/compiledJava/RecursiveWildcardUpperBound.fir.txt @@ -1,2 +1,2 @@ -public abstract interface RecursiveWildcardUpperBound?|> : R|kotlin/Any| { +public abstract interface RecursiveWildcardUpperBound, test/RecursiveWildcardUpperBound<*>?>!|> : R|kotlin/Any| { } diff --git a/compiler/testData/loadJava/compiledJava/constructor/ConstructorGenericUpperBound.fir.txt b/compiler/testData/loadJava/compiledJava/constructor/ConstructorGenericUpperBound.fir.txt index 41a6147a0c6..c1a21961491 100644 --- a/compiler/testData/loadJava/compiledJava/constructor/ConstructorGenericUpperBound.fir.txt +++ b/compiler/testData/loadJava/compiledJava/constructor/ConstructorGenericUpperBound.fir.txt @@ -1,4 +1,4 @@ public open class ConstructorGenericUpperBound : R|kotlin/Any| { - public constructor

(p: R|ft!|): R|test/ConstructorGenericUpperBound| + public constructor

!|>(p: R|ft!|): R|test/ConstructorGenericUpperBound| } diff --git a/compiler/testData/loadJava/compiledJava/kotlinSignature/AllBoundsInWhen.fir.txt b/compiler/testData/loadJava/compiledJava/kotlinSignature/AllBoundsInWhen.fir.txt index 02ed41f8f28..522ea5f2817 100644 --- a/compiler/testData/loadJava/compiledJava/kotlinSignature/AllBoundsInWhen.fir.txt +++ b/compiler/testData/loadJava/compiledJava/kotlinSignature/AllBoundsInWhen.fir.txt @@ -1,5 +1,5 @@ public open class AllBoundsInWhen : R|kotlin/Any| { - public open operator fun foo(): R|kotlin/Unit| + public open operator fun !|> foo(): R|kotlin/Unit| public constructor(): R|test/AllBoundsInWhen| diff --git a/compiler/testData/loadJava/compiledJava/kotlinSignature/MethodWithTypeParameters.fir.txt b/compiler/testData/loadJava/compiledJava/kotlinSignature/MethodWithTypeParameters.fir.txt index 5b03c145dfc..e61ae453517 100644 --- a/compiler/testData/loadJava/compiledJava/kotlinSignature/MethodWithTypeParameters.fir.txt +++ b/compiler/testData/loadJava/compiledJava/kotlinSignature/MethodWithTypeParameters.fir.txt @@ -1,5 +1,5 @@ public open class MethodWithTypeParameters : R|kotlin/Any| { - public open operator fun ?|> foo(a: R|ft!|, b: R|ft, kotlin/collections/List?>!|, list: R|ft, kotlin/collections/List?>!|): R|kotlin/Unit| + public open operator fun !|, R|ft, kotlin/collections/MutableList?>!|> foo(a: R|ft!|, b: R|ft, kotlin/collections/List?>!|, list: R|ft, kotlin/collections/List?>!|): R|kotlin/Unit| public constructor(): R|test/MethodWithTypeParameters| diff --git a/compiler/testData/loadJava/compiledJava/kotlinSignature/error/WrongTypeParameterBoundStructure1.fir.txt b/compiler/testData/loadJava/compiledJava/kotlinSignature/error/WrongTypeParameterBoundStructure1.fir.txt index 80f11a712dc..9eef640f07a 100644 --- a/compiler/testData/loadJava/compiledJava/kotlinSignature/error/WrongTypeParameterBoundStructure1.fir.txt +++ b/compiler/testData/loadJava/compiledJava/kotlinSignature/error/WrongTypeParameterBoundStructure1.fir.txt @@ -1,5 +1,5 @@ public open class WrongTypeParameterBoundStructure1 : R|kotlin/Any| { - public open operator fun ?|> foo(a: R|ft!|, b: R|ft, kotlin/collections/List?>!|): R|kotlin/Unit| + public open operator fun !|, R|ft, kotlin/collections/MutableList?>!|> foo(a: R|ft!|, b: R|ft, kotlin/collections/List?>!|): R|kotlin/Unit| public constructor(): R|test/WrongTypeParameterBoundStructure1| diff --git a/compiler/testData/loadJava/compiledJava/library/Max.fir.txt b/compiler/testData/loadJava/compiledJava/library/Max.fir.txt index bfb618ba7d0..bdcecbba93b 100644 --- a/compiler/testData/loadJava/compiledJava/library/Max.fir.txt +++ b/compiler/testData/loadJava/compiledJava/library/Max.fir.txt @@ -1,5 +1,5 @@ public open class Max : R|kotlin/Any| { - public open operator fun ?|> max(coll: R|ft, kotlin/collections/Collection?>!|): R|ft!| + public open operator fun !|, R|ft, kotlin/Comparable?>!|> max(coll: R|ft, kotlin/collections/Collection?>!|): R|ft!| public constructor(): R|test/Max| diff --git a/compiler/testData/loadJava/compiledJava/sam/GenericInterfaceParameterWithSelfBound.fir.txt b/compiler/testData/loadJava/compiledJava/sam/GenericInterfaceParameterWithSelfBound.fir.txt index b968aaad7d0..41565ef837d 100644 --- a/compiler/testData/loadJava/compiledJava/sam/GenericInterfaceParameterWithSelfBound.fir.txt +++ b/compiler/testData/loadJava/compiledJava/sam/GenericInterfaceParameterWithSelfBound.fir.txt @@ -1,4 +1,4 @@ -public abstract interface GenericInterfaceParameterWithSelfBound?|> : R|kotlin/Any| { +public abstract interface GenericInterfaceParameterWithSelfBound, test/GenericInterfaceParameterWithSelfBound?>!|> : R|kotlin/Any| { public abstract operator fun method(t: R|ft!|): R|ft!| } diff --git a/compiler/testData/loadJava/compiledJava/sam/GenericInterfaceParametersWithBounds.fir.txt b/compiler/testData/loadJava/compiledJava/sam/GenericInterfaceParametersWithBounds.fir.txt index 362f6adf8c8..a5b5a46b8d6 100644 --- a/compiler/testData/loadJava/compiledJava/sam/GenericInterfaceParametersWithBounds.fir.txt +++ b/compiler/testData/loadJava/compiledJava/sam/GenericInterfaceParametersWithBounds.fir.txt @@ -1,4 +1,4 @@ -public abstract interface GenericInterfaceParametersWithBounds?|, R|kotlin/Cloneable?|, B : R|kotlin/collections/MutableList?|> : R|kotlin/Any| { +public abstract interface GenericInterfaceParametersWithBounds, kotlin/Comparable?>!|, R|ft!|, B : R|ft, kotlin/collections/MutableList?>!|> : R|kotlin/Any| { public abstract operator fun method(a: R|ft!>, kotlin/Array!>?>!|, b: R|ft!|): R|kotlin/Unit| } diff --git a/compiler/testData/loadJava/compiledJava/sam/GenericMethodParameters.fir.txt b/compiler/testData/loadJava/compiledJava/sam/GenericMethodParameters.fir.txt index d055bab41f8..ab6629ac72d 100644 --- a/compiler/testData/loadJava/compiledJava/sam/GenericMethodParameters.fir.txt +++ b/compiler/testData/loadJava/compiledJava/sam/GenericMethodParameters.fir.txt @@ -1,4 +1,4 @@ public abstract interface GenericMethodParameters : R|kotlin/Any| { - public abstract operator fun ?|> method(a: R|ft!>, kotlin/Array!>?>!|, b: R|ft!|): R|kotlin/Unit| + public abstract operator fun !|, B : R|ft, kotlin/collections/MutableList?>!|> method(a: R|ft!>, kotlin/Array!>?>!|, b: R|ft!|): R|kotlin/Unit| } diff --git a/compiler/testData/loadJava/compiledJava/sam/adapters/TypeParameterOfMethod.fir.txt b/compiler/testData/loadJava/compiledJava/sam/adapters/TypeParameterOfMethod.fir.txt index c1fdc383d79..f68fb29544b 100644 --- a/compiler/testData/loadJava/compiledJava/sam/adapters/TypeParameterOfMethod.fir.txt +++ b/compiler/testData/loadJava/compiledJava/sam/adapters/TypeParameterOfMethod.fir.txt @@ -1,9 +1,9 @@ public open class TypeParameterOfMethod : R|kotlin/Any| { public open static operator fun max(comparator: R|ft!>, java/util/Comparator!>?>!|, value1: R|ft!|, value2: R|ft!|): R|ft!| - public open static operator fun max2(comparator: R|ft!>, java/util/Comparator!>?>!|, value1: R|ft!|, value2: R|ft!|): R|ft!| + public open static operator fun !|> max2(comparator: R|ft!>, java/util/Comparator!>?>!|, value1: R|ft!|, value2: R|ft!|): R|ft!| - public open static operator fun ?|> method(a: R|ft!>, java/util/Comparator!>?>!|, b: R|ft!|): R|kotlin/Unit| + public open static operator fun !|, B : R|ft, kotlin/collections/MutableList?>!|> method(a: R|ft!>, java/util/Comparator!>?>!|, b: R|ft!|): R|kotlin/Unit| public constructor(): R|test/TypeParameterOfMethod|