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:
committed by
TeamCityServer
parent
cc531149e5
commit
927723c766
+4
-3
@@ -121,7 +121,7 @@ object FirJavaGenericVarianceViolationTypeChecker : FirFunctionCallChecker() {
|
|||||||
lowerBoundWithoutCapturing.withNullability(ConeNullability.NULLABLE, typeCtx)
|
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 {
|
private fun ConeTypeProjection.removeOutProjection(positive: Boolean): ConeTypeProjection {
|
||||||
return when (this) {
|
return when (this) {
|
||||||
is ConeKotlinTypeProjectionOut -> if (positive) type else 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))
|
is ConeKotlinTypeProjectionIn -> ConeKotlinTypeProjectionIn(type.removeOutProjection(!positive))
|
||||||
|
// Don't remove nested projections for types at invariant position.
|
||||||
|
is ConeKotlinTypeConflictingProjection,
|
||||||
|
is ConeKotlinType,
|
||||||
is ConeStarProjection -> this
|
is ConeStarProjection -> this
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+19
@@ -8,11 +8,30 @@ import java.util.*;
|
|||||||
public class A {
|
public class A {
|
||||||
void foo(List<Object> x) {}
|
void foo(List<Object> x) {}
|
||||||
<T> void foo2(List<T> x) {}
|
<T> void foo2(List<T> x) {}
|
||||||
|
void foo3(Collection<? extends Object> x) {}
|
||||||
|
|
||||||
List<? extends Number> bar() {}
|
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
|
// FILE: main.kt
|
||||||
|
|
||||||
fun main(a: A) {
|
fun main(a: A) {
|
||||||
a.foo(<!JAVA_TYPE_MISMATCH!>a.bar()<!>)
|
a.foo(<!JAVA_TYPE_MISMATCH!>a.bar()<!>)
|
||||||
a.foo2(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())
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+10
@@ -5,9 +5,19 @@ public fun main(/*0*/ a: A): kotlin.Unit
|
|||||||
public open class A {
|
public open class A {
|
||||||
public constructor A()
|
public constructor A()
|
||||||
public/*package*/ open fun bar(): (kotlin.collections.MutableList<out kotlin.Number!>..kotlin.collections.List<kotlin.Number!>?)
|
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 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 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 </*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 hashCode(): kotlin.Int
|
||||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
Vendored
+21
@@ -8,14 +8,35 @@ import java.util.*;
|
|||||||
public class A {
|
public class A {
|
||||||
void foo(List<Object> x) {}
|
void foo(List<Object> x) {}
|
||||||
<T> void foo2(List<T> 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
|
// FILE: main.kt
|
||||||
|
|
||||||
fun main(a: A) {
|
fun main(a: A) {
|
||||||
a.foo(<!JAVA_TYPE_MISMATCH!>bar()<!>)
|
a.foo(<!JAVA_TYPE_MISMATCH!>bar()<!>)
|
||||||
a.foo2(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> {
|
fun bar() : MutableList<out Number> {
|
||||||
TODO()
|
TODO()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun bar2() : MutableList<MutableList<out Number>> {
|
||||||
|
TODO()
|
||||||
|
}
|
||||||
|
|||||||
Vendored
+10
@@ -1,6 +1,7 @@
|
|||||||
package
|
package
|
||||||
|
|
||||||
public fun bar(): kotlin.collections.MutableList<out kotlin.Number>
|
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 fun main(/*0*/ a: A): kotlin.Unit
|
||||||
|
|
||||||
public open class A {
|
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 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 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 </*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 hashCode(): kotlin.Int
|
||||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user