FIR checker: fix JAVA_TYPE_MISMATCH checker

First, the order of arguments is swapped.
Second, projection erasure for argType was too aggressive. We should
instead retain the projections that are under an invariant position.
This commit is contained in:
Tianyu Geng
2021-08-09 11:06:30 -07:00
committed by TeamCityServer
parent cc531149e5
commit 927723c766
5 changed files with 64 additions and 3 deletions
@@ -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
}
}
@@ -8,11 +8,30 @@ import java.util.*;
public class A {
void foo(List<Object> x) {}
<T> void foo2(List<T> x) {}
void foo3(Collection<? extends Object> x) {}
List<? extends Number> bar() {}
List<List<? extends Number>> bar2() {}
}
// FILE: B.java
import java.util.*;
public class B<T> {
public B(Collection<T> c) {
}
}
// FILE: main.kt
fun main(a: A) {
a.foo(<!JAVA_TYPE_MISMATCH!>a.bar()<!>)
a.foo2(a.bar())
a.foo3(a.bar())
B(a.bar())
a.foo(<!JAVA_TYPE_MISMATCH!>a.bar2()<!>)
a.foo2(a.bar2())
a.foo3(a.bar2())
B(a.bar2())
}
@@ -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<out kotlin.Number!>..kotlin.collections.List<kotlin.Number!>?)
public/*package*/ open fun bar2(): kotlin.collections.(Mutable)List<(kotlin.collections.MutableList<out kotlin.Number!>..kotlin.collections.List<kotlin.Number!>?)>!
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.Any!>!): kotlin.Unit
public/*package*/ open fun </*0*/ T : kotlin.Any!> foo2(/*0*/ x: kotlin.collections.(Mutable)List<T!>!): kotlin.Unit
public/*package*/ open fun foo3(/*0*/ x: (kotlin.collections.MutableCollection<out kotlin.Any!>..kotlin.collections.Collection<kotlin.Any!>?)): 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</*0*/ T : kotlin.Any!> {
public constructor B</*0*/ T : kotlin.Any!>(/*0*/ c: kotlin.collections.(Mutable)Collection<T!>!)
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
}
@@ -8,14 +8,35 @@ import java.util.*;
public class A {
void foo(List<Object> x) {}
<T> void foo2(List<T> x) {}
void foo3(Collection<? extends Object> x) {}
}
// FILE: B.java
import java.util.*;
public class B<T> {
public B(Collection<T> c) {
}
}
// FILE: main.kt
fun main(a: A) {
a.foo(<!JAVA_TYPE_MISMATCH!>bar()<!>)
a.foo2(bar())
a.foo3(bar())
B(bar())
a.foo(<!JAVA_TYPE_MISMATCH!>bar2()<!>)
a.foo2(bar2())
a.foo3(bar2())
B(bar2())
}
fun bar() : MutableList<out Number> {
TODO()
}
fun bar2() : MutableList<MutableList<out Number>> {
TODO()
}
@@ -1,6 +1,7 @@
package
public fun bar(): kotlin.collections.MutableList<out kotlin.Number>
public fun bar2(): kotlin.collections.MutableList<kotlin.collections.MutableList<out kotlin.Number>>
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.Any!>!): kotlin.Unit
public/*package*/ open fun </*0*/ T : kotlin.Any!> foo2(/*0*/ x: kotlin.collections.(Mutable)List<T!>!): kotlin.Unit
public/*package*/ open fun foo3(/*0*/ x: (kotlin.collections.MutableCollection<out kotlin.Any!>..kotlin.collections.Collection<kotlin.Any!>?)): 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</*0*/ T : kotlin.Any!> {
public constructor B</*0*/ T : kotlin.Any!>(/*0*/ c: kotlin.collections.(Mutable)Collection<T!>!)
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
}