Change "most specific return type" definition for fake overrides.

Given overridden descriptors D = d[i].
1. Find D*, subset of D:
  returnType(d* from D*) <: returnType(d) for each d from D.
  Always prefer var to val.
2. Prefer non-flexible return type to flexible.

Check for var/val overrides properly
(NB: this will report PROPERTY_TYPE_MISMATCH_ON_OVERRIDE
for all properties, not just overrides involving vars as it was before).
This commit is contained in:
Dmitry Petrov
2015-12-07 17:16:14 +03:00
parent 594039ac42
commit 94bea54db3
12 changed files with 312 additions and 48 deletions
@@ -16,11 +16,11 @@ abstract class B<H>() : A<H> {
override fun foo2() : <!RETURN_TYPE_MISMATCH_ON_OVERRIDE!>Unit<!> {
}
override val a : <!RETURN_TYPE_MISMATCH_ON_OVERRIDE!>Double<!> = 1.toDouble()
override val <!RETURN_TYPE_MISMATCH_ON_OVERRIDE!>a1<!> = 1.toDouble()
override val a : <!PROPERTY_TYPE_MISMATCH_ON_OVERRIDE!>Double<!> = 1.toDouble()
override val <!PROPERTY_TYPE_MISMATCH_ON_OVERRIDE!>a1<!> = 1.toDouble()
abstract override fun <X> g() : <!RETURN_TYPE_MISMATCH_ON_OVERRIDE!>Int<!>
abstract override fun <X> g1() : <!RETURN_TYPE_MISMATCH_ON_OVERRIDE!>List<X><!>
abstract override val g : <!RETURN_TYPE_MISMATCH_ON_OVERRIDE!>Iterator<Int><!>
abstract override val g : <!PROPERTY_TYPE_MISMATCH_ON_OVERRIDE!>Iterator<Int><!>
}
@@ -7,7 +7,7 @@ interface A {
}
class AImpl: A {
override val <!RETURN_TYPE_MISMATCH_ON_OVERRIDE!>prop<!> by Delegate()
override val <!PROPERTY_TYPE_MISMATCH_ON_OVERRIDE!>prop<!> by Delegate()
}
fun foo() {
@@ -10,9 +10,9 @@ interface Three {
public fun foo(): String
}
<!MANY_IMPL_MEMBER_NOT_IMPLEMENTED, MANY_IMPL_MEMBER_NOT_IMPLEMENTED!>class Test123<!>(val v1: One, val v2: Two, val v3: Three) : One by v1, Two by v2, Three by v3 { }
<!MANY_IMPL_MEMBER_NOT_IMPLEMENTED, MANY_IMPL_MEMBER_NOT_IMPLEMENTED!>class Test132<!>(val v1: One, val v2: Two, val v3: Three) : One by v1, Three by v3, Two by v2 { }
<!MANY_IMPL_MEMBER_NOT_IMPLEMENTED, MANY_IMPL_MEMBER_NOT_IMPLEMENTED, RETURN_TYPE_MISMATCH_ON_INHERITANCE!>class Test123<!>(val v1: One, val v2: Two, val v3: Three) : One by v1, Two by v2, Three by v3 { }
<!MANY_IMPL_MEMBER_NOT_IMPLEMENTED, MANY_IMPL_MEMBER_NOT_IMPLEMENTED, RETURN_TYPE_MISMATCH_ON_INHERITANCE!>class Test132<!>(val v1: One, val v2: Two, val v3: Three) : One by v1, Three by v3, Two by v2 { }
<!MANY_IMPL_MEMBER_NOT_IMPLEMENTED, MANY_IMPL_MEMBER_NOT_IMPLEMENTED!>class Test312<!>(val v1: One, val v2: Two, val v3: Three) : Three by v3, One by v1, Two by v2 { }
<!MANY_IMPL_MEMBER_NOT_IMPLEMENTED, MANY_IMPL_MEMBER_NOT_IMPLEMENTED!>class Test321<!>(val v1: One, val v2: Two, val v3: Three) : Three by v3, Two by v2, One by v1 { }
<!MANY_IMPL_MEMBER_NOT_IMPLEMENTED, MANY_IMPL_MEMBER_NOT_IMPLEMENTED!>class Test231<!>(val v1: One, val v2: Two, val v3: Three) : Two by v2, Three by v3, One by v1 { }
<!MANY_IMPL_MEMBER_NOT_IMPLEMENTED, MANY_IMPL_MEMBER_NOT_IMPLEMENTED!>class Test213<!>(val v1: One, val v2: Two, val v3: Three) : Two by v2, One by v1, Three by v3 { }
<!MANY_IMPL_MEMBER_NOT_IMPLEMENTED, MANY_IMPL_MEMBER_NOT_IMPLEMENTED, RETURN_TYPE_MISMATCH_ON_INHERITANCE!>class Test231<!>(val v1: One, val v2: Two, val v3: Three) : Two by v2, Three by v3, One by v1 { }
<!MANY_IMPL_MEMBER_NOT_IMPLEMENTED, MANY_IMPL_MEMBER_NOT_IMPLEMENTED, RETURN_TYPE_MISMATCH_ON_INHERITANCE!>class Test213<!>(val v1: One, val v2: Two, val v3: Three) : Two by v2, One by v1, Three by v3 { }
@@ -60,7 +60,7 @@ public interface KDerived1b : J, K1 {
public interface KDerived2a : K2, J {
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract override /*2*/ /*fake_override*/ fun foo(): kotlin.String!
public abstract override /*2*/ /*fake_override*/ fun foo(): kotlin.String?
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -30,9 +30,14 @@ interface Test5 : ILNS, IMLS, J
interface Test6 : ILNS, J, IMLS
interface Test7 : J, ILNS, IMLS
// ILS and IMLNS are incompatible
// Return types of ILS::foo and IMLNS::foo are incompatible themselves.
// However, return type of J::foo is (Mutable)List<String!>!,
// which is subtype of both List<String> and MutalbeList<String?>.
// Thus, inheriting from J, IMLNS, and ILS is Ok,
// but inheriting from IMLNS and ILS is not.
interface Test8 : J, IMLNS, ILS
interface Test9 : IMLNS, J, ILS
interface Test10 : IMLNS, ILS, J
<!RETURN_TYPE_MISMATCH_ON_INHERITANCE!>interface Test8<!> : J, IMLNS, ILS
<!RETURN_TYPE_MISMATCH_ON_INHERITANCE!>interface Test9<!> : IMLNS, J, ILS
<!RETURN_TYPE_MISMATCH_ON_INHERITANCE!>interface Test10<!> : IMLNS, ILS, J
<!RETURN_TYPE_MISMATCH_ON_INHERITANCE!>interface Test11<!> : IMLNS, ILS
@@ -46,7 +46,7 @@ public interface Test1 : ILNS, J {
public interface Test10 : IMLNS, ILS, J {
public open override /*3*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract override /*3*/ /*fake_override*/ fun foo(): kotlin.MutableList<kotlin.String?>
public abstract override /*3*/ /*fake_override*/ fun foo(): kotlin.(Mutable)List<kotlin.String!>!
public open override /*3*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*3*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -102,14 +102,14 @@ public interface Test7 : J, ILNS, IMLS {
public interface Test8 : J, IMLNS, ILS {
public open override /*3*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract override /*3*/ /*fake_override*/ fun foo(): kotlin.MutableList<kotlin.String?>
public abstract override /*3*/ /*fake_override*/ fun foo(): kotlin.(Mutable)List<kotlin.String!>!
public open override /*3*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*3*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface Test9 : IMLNS, J, ILS {
public open override /*3*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract override /*3*/ /*fake_override*/ fun foo(): kotlin.MutableList<kotlin.String?>
public abstract override /*3*/ /*fake_override*/ fun foo(): kotlin.(Mutable)List<kotlin.String!>!
public open override /*3*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*3*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -0,0 +1,56 @@
// FILE: JFooWithUpperBound.java
public interface JFooWithUpperBound<T extends IBase> {
T foo();
}
// FILE: JFooWithUpperBoundDerived.java
public interface JFooWithUpperBoundDerived<T extends IBase> extends JFooWithUpperBound<T> {
}
// FILE: JCFooWithUpperBound.java
public class JCFooWithUpperBound<T extends IBase> {
public T foo() {
return null;
}
}
// FILE: JCFooWithUpperBoundDerived.java
public class JCFooWithUpperBoundDerived<T extends IBase> extends JCFooWithUpperBound<T> {
}
// FILE: K.kt
interface IBase
interface IDerived : IBase
interface IFooWithUpperBound<T : IBase> {
fun foo(): T
}
interface IFooT<T> {
fun foo(): T
}
interface IFoo {
fun foo(): IBase
}
interface IFooDerived : IFoo {
override fun foo(): IDerived
}
interface IFooWithUpperBoundDerived<T : IBase> : IFooWithUpperBound<T>
interface Test1<T : IBase> : IFooWithUpperBound<T>, IFoo
interface Test2<T : IBase> : IFooT<T>, IFoo
interface Test3<T : IDerived> : IFooWithUpperBoundDerived<T>, IFooDerived
interface Test4<T : IBase> : JFooWithUpperBound<T>, IFoo
interface Test5<T : IDerived> : JFooWithUpperBoundDerived<T>, IFooDerived
class Test6<T : IBase> : JCFooWithUpperBound<T>(), IFoo
class Test7<T : IDerived> : JCFooWithUpperBoundDerived<T>(), IFooDerived
@@ -0,0 +1,132 @@
package
public /*synthesized*/ fun </*0*/ T : IBase!> JFooWithUpperBound(/*0*/ function: () -> T!): JFooWithUpperBound<T>
public /*synthesized*/ fun </*0*/ T : IBase!> JFooWithUpperBoundDerived(/*0*/ function: () -> T!): JFooWithUpperBoundDerived<T>
public interface IBase {
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
}
public interface IDerived : IBase {
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
}
public interface IFoo {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract fun foo(): IBase
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface IFooDerived : IFoo {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract override /*1*/ fun foo(): IDerived
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface IFooT</*0*/ T> {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract fun foo(): T
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface IFooWithUpperBound</*0*/ T : IBase> {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract fun foo(): T
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface IFooWithUpperBoundDerived</*0*/ T : IBase> : IFooWithUpperBound<T> {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract override /*1*/ /*fake_override*/ fun foo(): T
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public open class JCFooWithUpperBound</*0*/ T : IBase!> {
public constructor JCFooWithUpperBound</*0*/ T : IBase!>()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open fun foo(): T!
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public open class JCFooWithUpperBoundDerived</*0*/ T : IBase!> : JCFooWithUpperBound<T!> {
public constructor JCFooWithUpperBoundDerived</*0*/ T : IBase!>()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun foo(): T!
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface JFooWithUpperBound</*0*/ T : IBase!> {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract fun foo(): T!
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface JFooWithUpperBoundDerived</*0*/ T : IBase!> : JFooWithUpperBound<T!> {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract override /*1*/ /*fake_override*/ fun foo(): T!
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface Test1</*0*/ T : IBase> : IFooWithUpperBound<T>, IFoo {
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract override /*2*/ /*fake_override*/ fun foo(): T
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface Test2</*0*/ T : IBase> : IFooT<T>, IFoo {
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract override /*2*/ /*fake_override*/ fun foo(): T
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface Test3</*0*/ T : IDerived> : IFooWithUpperBoundDerived<T>, IFooDerived {
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract override /*2*/ /*fake_override*/ fun foo(): T
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface Test4</*0*/ T : IBase> : JFooWithUpperBound<T>, IFoo {
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract override /*2*/ /*fake_override*/ fun foo(): T!
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface Test5</*0*/ T : IDerived> : JFooWithUpperBoundDerived<T>, IFooDerived {
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract override /*2*/ /*fake_override*/ fun foo(): T!
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class Test6</*0*/ T : IBase> : JCFooWithUpperBound<T>, IFoo {
public constructor Test6</*0*/ T : IBase>()
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*2*/ /*fake_override*/ fun foo(): T!
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class Test7</*0*/ T : IDerived> : JCFooWithUpperBoundDerived<T>, IFooDerived {
public constructor Test7</*0*/ T : IDerived>()
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*2*/ /*fake_override*/ fun foo(): T!
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
}