KT-2729 Warn on 'T?' where 'T' has a nullable upper bound
This commit is contained in:
@@ -86,6 +86,6 @@ fun <T> joinG(x : Int, vararg a : T) : String {
|
||||
return b.toString()
|
||||
}
|
||||
|
||||
fun <T> joinT(<!UNUSED_PARAMETER!>x<!> : Int, vararg <!UNUSED_PARAMETER!>a<!> : T) : T? {
|
||||
fun <T: Any> joinT(<!UNUSED_PARAMETER!>x<!> : Int, vararg <!UNUSED_PARAMETER!>a<!> : T) : T? {
|
||||
return null
|
||||
}
|
||||
@@ -20,7 +20,7 @@ fun test(expectedSum : Int, vararg data : Int) {
|
||||
assertEquals(actualSum, expectedSum, "\ndata = ${Arrays.toString(data)}\n" +
|
||||
"sum(data) = ${actualSum}, but must be $expectedSum ")
|
||||
}
|
||||
fun assertEquals<T>(actual : T?, expected : T?, message : Any? = null) {
|
||||
fun assertEquals<T: Any>(actual : T?, expected : T?, message : Any? = null) {
|
||||
if (actual != expected) {
|
||||
if (message == null)
|
||||
throw AssertionError()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
fun fooT22<T>() : T? {
|
||||
fun fooT22<T: Any>() : T? {
|
||||
return null
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package d
|
||||
|
||||
fun <T> joinT(<!UNUSED_PARAMETER!>x<!>: Int, vararg <!UNUSED_PARAMETER!>a<!>: T): T? {
|
||||
fun <T: Any> joinT(<!UNUSED_PARAMETER!>x<!>: Int, vararg <!UNUSED_PARAMETER!>a<!>: T): T? {
|
||||
return null
|
||||
}
|
||||
|
||||
fun <T> joinT(<!UNUSED_PARAMETER!>x<!>: Any, <!UNUSED_PARAMETER!>y<!>: T): T? {
|
||||
fun <T: Any> joinT(<!UNUSED_PARAMETER!>x<!>: Any, <!UNUSED_PARAMETER!>y<!>: T): T? {
|
||||
return null
|
||||
}
|
||||
|
||||
|
||||
@@ -24,4 +24,4 @@ abstract class Buggy {
|
||||
}
|
||||
|
||||
//from library
|
||||
fun <T> Iterable<T>.find(<!UNUSED_PARAMETER!>predicate<!>: (T) -> Boolean) : T? {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
fun <T: Any> Iterable<T>.find(<!UNUSED_PARAMETER!>predicate<!>: (T) -> Boolean) : T? {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||
@@ -6,8 +6,8 @@ trait MyType {}
|
||||
class MyClass<T> : MyType {}
|
||||
|
||||
public open class HttpResponse() {
|
||||
public open fun parseAs<T>(dataClass : MyClass<T>) : T? {
|
||||
return null
|
||||
public open fun parseAs<T>(dataClass : MyClass<T>) : T {
|
||||
throw Exception()
|
||||
}
|
||||
public open fun parseAs(dataType : MyType) : Any? {
|
||||
return null
|
||||
@@ -16,5 +16,5 @@ public open class HttpResponse() {
|
||||
|
||||
fun test<R> (httpResponse: HttpResponse, rtype: MyClass<R>) {
|
||||
val res = httpResponse.parseAs( rtype )
|
||||
res : R? //type mismatch: required R?, found T?
|
||||
res : R //type mismatch: required R, found T
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ fun getJavaClass<T>() : java.lang.Class<T> { <!NO_RETURN_IN_FUNCTION_WITH_BLOCK_
|
||||
|
||||
public class Throwables() {
|
||||
class object {
|
||||
public fun propagateIfInstanceOf<X : Throwable?>(throwable : Throwable?, declaredType : Class<X?>?) : Unit {
|
||||
public fun propagateIfInstanceOf<X : Throwable?>(throwable : Throwable?, declaredType : Class<X<!BASE_WITH_NULLABLE_UPPER_BOUND!>?<!>>?) : Unit {
|
||||
if (((throwable != null) && declaredType?.isInstance(throwable)!!))
|
||||
{
|
||||
throw declaredType?.cast(throwable)!!
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
fun foo<T>(vararg <!UNUSED_PARAMETER!>ts<!>: T): T? = null
|
||||
fun foo<T: Any>(vararg <!UNUSED_PARAMETER!>ts<!>: T): T? = null
|
||||
|
||||
class Pair<A>(a: A)
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
val <T, E> T.foo : E?
|
||||
val <T, E> T.foo : E<!BASE_WITH_NULLABLE_UPPER_BOUND!>?<!>
|
||||
get() = null
|
||||
|
||||
fun test(): Int? {
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
fun nonMisleadingNullable<NN: Any, NNN: NN>(
|
||||
<!UNUSED_PARAMETER!>nn<!>: NN?,
|
||||
<!UNUSED_PARAMETER!>nnn<!>: NNN?
|
||||
) {}
|
||||
|
||||
fun twoBounds<NN: Any, TWO_BOUNDS: Any>(
|
||||
<!UNUSED_PARAMETER!>tb<!>: TWO_BOUNDS?
|
||||
|
||||
) where TWO_BOUNDS : NN {}
|
||||
|
||||
fun misleadingNullableSimple<T, N: T, INDIRECT: N>(
|
||||
<!UNUSED_PARAMETER!>t<!>: T<!BASE_WITH_NULLABLE_UPPER_BOUND!>?<!>,
|
||||
<!UNUSED_PARAMETER!>t2<!>: T<!BASE_WITH_NULLABLE_UPPER_BOUND!>?<!>,
|
||||
<!UNUSED_PARAMETER!>n<!>: N<!BASE_WITH_NULLABLE_UPPER_BOUND!>?<!>,
|
||||
<!UNUSED_PARAMETER!>ind<!>: INDIRECT<!BASE_WITH_NULLABLE_UPPER_BOUND!>?<!>
|
||||
) {}
|
||||
|
||||
fun misleadingNullableMultiBound<FIRST_BOUND: Any?, SECOND_BOUND: Any>(
|
||||
<!UNUSED_PARAMETER!>fb<!>: FIRST_BOUND<!BASE_WITH_NULLABLE_UPPER_BOUND!>?<!>,
|
||||
<!UNUSED_PARAMETER!>sb<!>: SECOND_BOUND<!BASE_WITH_NULLABLE_UPPER_BOUND!>?<!>
|
||||
) where FIRST_BOUND: Any, SECOND_BOUND: Any? {
|
||||
}
|
||||
|
||||
fun interactionWithRedundant<T>(<!UNUSED_PARAMETER!>t<!>: T<!BASE_WITH_NULLABLE_UPPER_BOUND!>?<!><!REDUNDANT_NULLABLE!>?<!>) {}
|
||||
@@ -7,6 +7,6 @@ import html.* // Must not be an error
|
||||
|
||||
package html
|
||||
|
||||
abstract class Factory<T> {
|
||||
abstract class Factory<T: Any> {
|
||||
fun create() : T? = null
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// KT-312 Nullability problem when a nullable version of a generic type is returned
|
||||
|
||||
fun <T> Array<out T>.safeGet(index : Int) : T? {
|
||||
fun <T> Array<out T>.safeGet(index : Int) : T<!BASE_WITH_NULLABLE_UPPER_BOUND!>?<!> {
|
||||
return if (index < size) this[index] else null
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ fun getJavaClass<T>() : java.lang.Class<T> { return "" <!CAST_NEVER_SUCCEEDS!>as
|
||||
|
||||
public class Throwables() {
|
||||
class object {
|
||||
public fun propagateIfInstanceOf<X : Throwable?>(throwable : Throwable?, declaredType : Class<X?>?) {
|
||||
public fun propagateIfInstanceOf<X : Throwable?>(throwable : Throwable?, declaredType : Class<X<!BASE_WITH_NULLABLE_UPPER_BOUND!>?<!>>?) {
|
||||
if (((throwable != null) && declaredType?.isInstance(throwable)!!))
|
||||
{
|
||||
throw declaredType?.cast(throwable)!!
|
||||
|
||||
Reference in New Issue
Block a user