Report error on more than one class bound for type parameters

Such code may behave unexpectedly when compiled to JVM
This commit is contained in:
Alexander Udalov
2015-11-20 19:42:35 +03:00
parent 5541224288
commit 21e64e02bd
13 changed files with 184 additions and 51 deletions
+1 -1
View File
@@ -48,7 +48,7 @@ class Bar<T : <!FINAL_UPPER_BOUND!>Foo<!>>
class Buzz<T> where T : <!FINAL_UPPER_BOUND!>Bar<<!UPPER_BOUND_VIOLATED!>Int<!>><!>, T : <!UNRESOLVED_REFERENCE!>nioho<!>
class X<T : <!FINAL_UPPER_BOUND!>Foo<!>>
class Y<<!CONFLICTING_UPPER_BOUNDS!>T<!>> where T : <!FINAL_UPPER_BOUND!>Foo<!>, T : <!FINAL_UPPER_BOUND!>Bar<Foo><!>
class Y<<!CONFLICTING_UPPER_BOUNDS!>T<!>> where T : <!FINAL_UPPER_BOUND!>Foo<!>, T : <!ONLY_ONE_CLASS_BOUND_ALLOWED, FINAL_UPPER_BOUND!>Bar<Foo><!>
fun <T> test2(t : T)
where
@@ -15,10 +15,4 @@ fun <T, N: T, INDIRECT: N> misleadingNullableSimple(
<!UNUSED_PARAMETER!>ind<!>: INDIRECT?
) {}
fun <FIRST_BOUND, SECOND_BOUND> misleadingNullableMultiBound(
<!UNUSED_PARAMETER!>fb<!>: FIRST_BOUND?,
<!UNUSED_PARAMETER!>sb<!>: SECOND_BOUND?
) where FIRST_BOUND: Any?, FIRST_BOUND: Any, SECOND_BOUND: Any, SECOND_BOUND: Any? {
}
fun <T> interactionWithRedundant(<!UNUSED_PARAMETER!>t<!>: T?<!REDUNDANT_NULLABLE!>?<!>) {}
@@ -1,7 +1,6 @@
package
public fun </*0*/ T> interactionWithRedundant(/*0*/ t: T?): kotlin.Unit
public fun </*0*/ FIRST_BOUND, /*1*/ SECOND_BOUND : kotlin.Any> misleadingNullableMultiBound(/*0*/ fb: FIRST_BOUND?, /*1*/ sb: SECOND_BOUND?): kotlin.Unit where FIRST_BOUND : kotlin.Any, SECOND_BOUND : kotlin.Any?
public fun </*0*/ T, /*1*/ N : T, /*2*/ INDIRECT : N> misleadingNullableSimple(/*0*/ t: T?, /*1*/ t2: T?, /*2*/ n: N?, /*3*/ ind: INDIRECT?): kotlin.Unit
public fun </*0*/ NN : kotlin.Any, /*1*/ NNN : NN> nonMisleadingNullable(/*0*/ nn: NN?, /*1*/ nnn: NNN?): kotlin.Unit
public fun </*0*/ NN : kotlin.Any, /*1*/ TWO_BOUNDS : kotlin.Any> twoBounds(/*0*/ tb: TWO_BOUNDS?): kotlin.Unit where TWO_BOUNDS : NN
@@ -0,0 +1,18 @@
open class C1
open class C2
open class C3 : C2()
class A1<T> where T : C1, T : <!ONLY_ONE_CLASS_BOUND_ALLOWED!>C2<!>
class A2<T> where T : C1, T : <!ONLY_ONE_CLASS_BOUND_ALLOWED!>C2<!>, T : <!ONLY_ONE_CLASS_BOUND_ALLOWED!>C3<!>
class A3<T> where T : C2, T : <!ONLY_ONE_CLASS_BOUND_ALLOWED!>C3<!>
class A4<T> where T : C3, T : <!ONLY_ONE_CLASS_BOUND_ALLOWED!>C2<!>
fun <T> f1() where T : C1, T : <!ONLY_ONE_CLASS_BOUND_ALLOWED!>C2<!>, T : <!ONLY_ONE_CLASS_BOUND_ALLOWED!>C3<!> {}
fun <T> f2() where T : C2, T : <!ONLY_ONE_CLASS_BOUND_ALLOWED!>C3<!> {}
fun <T> f3() where T : C3, T : <!ONLY_ONE_CLASS_BOUND_ALLOWED!>C2<!> {}
enum class E1
class A5<<!CONFLICTING_UPPER_BOUNDS!>T<!>> where T : C1, T : <!ONLY_ONE_CLASS_BOUND_ALLOWED, FINAL_UPPER_BOUND!>E1<!>
object O1
class A6<<!CONFLICTING_UPPER_BOUNDS!>T<!>> where T : <!FINAL_UPPER_BOUND!>O1<!>, T : <!ONLY_ONE_CLASS_BOUND_ALLOWED!>C2<!>
@@ -0,0 +1,91 @@
package
public fun </*0*/ T : C1> f1(): kotlin.Unit where T : C2, T : C3
public fun </*0*/ T : C2> f2(): kotlin.Unit where T : C3
public fun </*0*/ T : C3> f3(): kotlin.Unit where T : C2
public final class A1</*0*/ T : C1> where T : C2 {
public constructor A1</*0*/ T : C1>() where T : C2
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 final class A2</*0*/ T : C1> where T : C2, T : C3 {
public constructor A2</*0*/ T : C1>() where T : C2, T : C3
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 final class A3</*0*/ T : C2> where T : C3 {
public constructor A3</*0*/ T : C2>() where T : C3
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 final class A4</*0*/ T : C3> where T : C2 {
public constructor A4</*0*/ T : C3>() where T : C2
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 final class A5</*0*/ T : C1> where T : E1 {
public constructor A5</*0*/ T : C1>() where T : E1
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 final class A6</*0*/ T : O1> where T : C2 {
public constructor A6</*0*/ T : O1>() where T : C2
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 open class C1 {
public constructor C1()
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 open class C2 {
public constructor C2()
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 open class C3 : C2 {
public constructor C3()
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 final enum class E1 : kotlin.Enum<E1> {
private constructor E1()
public final override /*1*/ /*fake_override*/ val name: kotlin.String
public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: E1): kotlin.Int
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
// Static members
@kotlin.Deprecated(message = "Use 'values()' function instead", replaceWith = kotlin.ReplaceWith(expression = "this.values()", imports = {})) public final /*synthesized*/ val values: kotlin.Array<E1>
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): E1
public final /*synthesized*/ fun values(): kotlin.Array<E1>
}
public object O1 {
private constructor O1()
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
}
@@ -1,6 +1,6 @@
fun <<!UPPER_BOUND_CANNOT_BE_ARRAY!>A : Array<Any><!>> f1() {}
fun <T, <!UPPER_BOUND_CANNOT_BE_ARRAY!>A : Array<out T><!>> f2() {}
fun <S, T : S, <!INCONSISTENT_TYPE_PARAMETER_BOUNDS, UPPER_BOUND_CANNOT_BE_ARRAY!>A<!>> f3() where A : Array<out S>, A : Array<out T> {}
fun <S, T : S, <!INCONSISTENT_TYPE_PARAMETER_BOUNDS, UPPER_BOUND_CANNOT_BE_ARRAY!>A<!>> f3() where A : Array<out S>, A : <!ONLY_ONE_CLASS_BOUND_ALLOWED!>Array<out T><!> {}
fun <<!UPPER_BOUND_CANNOT_BE_ARRAY!>T : <!FINAL_UPPER_BOUND!>IntArray<!><!>> f4() {}
@@ -9,7 +9,7 @@ fun <<!UPPER_BOUND_CANNOT_BE_ARRAY!>T<!>> f5() where T : Array<Any> {}
val <<!UPPER_BOUND_CANNOT_BE_ARRAY!>T : Array<Any?><!>> T.v: String get() = ""
class C2<T, <!UPPER_BOUND_CANNOT_BE_ARRAY!>A : Array<out T><!>>
interface C3<S, T : S, <!INCONSISTENT_TYPE_PARAMETER_BOUNDS, UPPER_BOUND_CANNOT_BE_ARRAY!>A<!>> where A : Array<out S>, A : Array<out T>
interface C3<S, T : S, <!INCONSISTENT_TYPE_PARAMETER_BOUNDS, UPPER_BOUND_CANNOT_BE_ARRAY!>A<!>> where A : Array<out S>, A : <!ONLY_ONE_CLASS_BOUND_ALLOWED!>Array<out T><!>
fun foo() {
class C1<<!UPPER_BOUND_CANNOT_BE_ARRAY!>A : Array<Any><!>> {