diff --git a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/expression/FirJavaGenericVarianceViolationTypeChecker.kt b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/expression/FirJavaGenericVarianceViolationTypeChecker.kt index e634f4f720c..e7e2fdde30f 100644 --- a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/expression/FirJavaGenericVarianceViolationTypeChecker.kt +++ b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/expression/FirJavaGenericVarianceViolationTypeChecker.kt @@ -121,7 +121,7 @@ object FirJavaGenericVarianceViolationTypeChecker : FirFunctionCallChecker() { lowerBoundWithoutCapturing.withNullability(ConeNullability.NULLABLE, typeCtx) ) ) { - reporter.reportOn(arg.source, FirErrors.JAVA_TYPE_MISMATCH, argType, expectedType, context) + reporter.reportOn(arg.source, FirErrors.JAVA_TYPE_MISMATCH, expectedType, argType, context) } } } @@ -161,9 +161,10 @@ object FirJavaGenericVarianceViolationTypeChecker : FirFunctionCallChecker() { private fun ConeTypeProjection.removeOutProjection(positive: Boolean): ConeTypeProjection { return when (this) { is ConeKotlinTypeProjectionOut -> if (positive) type else this - is ConeKotlinType -> this.removeOutProjection(true) - is ConeKotlinTypeConflictingProjection -> ConeKotlinTypeConflictingProjection(type.removeOutProjection(true)) is ConeKotlinTypeProjectionIn -> ConeKotlinTypeProjectionIn(type.removeOutProjection(!positive)) + // Don't remove nested projections for types at invariant position. + is ConeKotlinTypeConflictingProjection, + is ConeKotlinType, is ConeStarProjection -> this } } diff --git a/compiler/testData/diagnostics/tests/platformTypes/genericVarianceViolation/javaOutProjection.kt b/compiler/testData/diagnostics/tests/platformTypes/genericVarianceViolation/javaOutProjection.kt index 6ec3dfb6a6a..b25b4a04cfb 100644 --- a/compiler/testData/diagnostics/tests/platformTypes/genericVarianceViolation/javaOutProjection.kt +++ b/compiler/testData/diagnostics/tests/platformTypes/genericVarianceViolation/javaOutProjection.kt @@ -8,11 +8,30 @@ import java.util.*; public class A { void foo(List x) {} void foo2(List x) {} + void foo3(Collection x) {} + List bar() {} + List> bar2() {} +} + +// FILE: B.java + +import java.util.*; + +public class B { + public B(Collection c) { + + } } // FILE: main.kt fun main(a: A) { a.foo(a.bar()) a.foo2(a.bar()) + a.foo3(a.bar()) + B(a.bar()) + a.foo(a.bar2()) + a.foo2(a.bar2()) + a.foo3(a.bar2()) + B(a.bar2()) } diff --git a/compiler/testData/diagnostics/tests/platformTypes/genericVarianceViolation/javaOutProjection.txt b/compiler/testData/diagnostics/tests/platformTypes/genericVarianceViolation/javaOutProjection.txt index 84b399a84d0..e9b2b1c2b43 100644 --- a/compiler/testData/diagnostics/tests/platformTypes/genericVarianceViolation/javaOutProjection.txt +++ b/compiler/testData/diagnostics/tests/platformTypes/genericVarianceViolation/javaOutProjection.txt @@ -5,9 +5,19 @@ public fun main(/*0*/ a: A): kotlin.Unit public open class A { public constructor A() public/*package*/ open fun bar(): (kotlin.collections.MutableList..kotlin.collections.List?) + public/*package*/ open fun bar2(): kotlin.collections.(Mutable)List<(kotlin.collections.MutableList..kotlin.collections.List?)>! public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean public/*package*/ open fun foo(/*0*/ x: kotlin.collections.(Mutable)List!): kotlin.Unit public/*package*/ open fun foo2(/*0*/ x: kotlin.collections.(Mutable)List!): kotlin.Unit + public/*package*/ open fun foo3(/*0*/ x: (kotlin.collections.MutableCollection..kotlin.collections.Collection?)): kotlin.Unit public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String } + +public open class B { + public constructor B(/*0*/ c: kotlin.collections.(Mutable)Collection!) + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + diff --git a/compiler/testData/diagnostics/tests/platformTypes/genericVarianceViolation/kotlinOutProjection.kt b/compiler/testData/diagnostics/tests/platformTypes/genericVarianceViolation/kotlinOutProjection.kt index 5e752bd438c..2eaf3bcb664 100644 --- a/compiler/testData/diagnostics/tests/platformTypes/genericVarianceViolation/kotlinOutProjection.kt +++ b/compiler/testData/diagnostics/tests/platformTypes/genericVarianceViolation/kotlinOutProjection.kt @@ -8,14 +8,35 @@ import java.util.*; public class A { void foo(List x) {} void foo2(List x) {} + void foo3(Collection x) {} +} + +// FILE: B.java + +import java.util.*; + +public class B { + public B(Collection c) { + + } } // FILE: main.kt fun main(a: A) { a.foo(bar()) a.foo2(bar()) + a.foo3(bar()) + B(bar()) + a.foo(bar2()) + a.foo2(bar2()) + a.foo3(bar2()) + B(bar2()) } fun bar() : MutableList { TODO() } + +fun bar2() : MutableList> { + TODO() +} diff --git a/compiler/testData/diagnostics/tests/platformTypes/genericVarianceViolation/kotlinOutProjection.txt b/compiler/testData/diagnostics/tests/platformTypes/genericVarianceViolation/kotlinOutProjection.txt index 9c9c7b034b7..3a83dba617e 100644 --- a/compiler/testData/diagnostics/tests/platformTypes/genericVarianceViolation/kotlinOutProjection.txt +++ b/compiler/testData/diagnostics/tests/platformTypes/genericVarianceViolation/kotlinOutProjection.txt @@ -1,6 +1,7 @@ package public fun bar(): kotlin.collections.MutableList +public fun bar2(): kotlin.collections.MutableList> public fun main(/*0*/ a: A): kotlin.Unit public open class A { @@ -8,6 +9,15 @@ public open class A { public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean public/*package*/ open fun foo(/*0*/ x: kotlin.collections.(Mutable)List!): kotlin.Unit public/*package*/ open fun foo2(/*0*/ x: kotlin.collections.(Mutable)List!): kotlin.Unit + public/*package*/ open fun foo3(/*0*/ x: (kotlin.collections.MutableCollection..kotlin.collections.Collection?)): kotlin.Unit public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String } + +public open class B { + public constructor B(/*0*/ c: kotlin.collections.(Mutable)Collection!) + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} +