Fix warning about useless elvis when generics are involved
#KT-13648 Fixed
This commit is contained in:
+2
-2
@@ -943,7 +943,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
|||||||
|
|
||||||
private static boolean isKnownToBeNotNull(KtExpression expression, KotlinType jetType, ExpressionTypingContext context) {
|
private static boolean isKnownToBeNotNull(KtExpression expression, KotlinType jetType, ExpressionTypingContext context) {
|
||||||
DataFlowValue dataFlowValue = createDataFlowValue(expression, jetType, context);
|
DataFlowValue dataFlowValue = createDataFlowValue(expression, jetType, context);
|
||||||
return !context.dataFlowInfo.getStableNullability(dataFlowValue).canBeNull();
|
return context.dataFlowInfo.getStableNullability(dataFlowValue) == Nullability.NOT_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1272,7 +1272,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
|||||||
}
|
}
|
||||||
assert leftTypeInfo != null : "Left expression was not processed: " + expression;
|
assert leftTypeInfo != null : "Left expression was not processed: " + expression;
|
||||||
KotlinType leftType = leftTypeInfo.getType();
|
KotlinType leftType = leftTypeInfo.getType();
|
||||||
if (leftType != null && isKnownToBeNotNull(left, leftType, context)) {
|
if (leftType != null && (!TypeUtils.isNullableType(leftType) || isKnownToBeNotNull(left, leftType, context))) {
|
||||||
context.trace.report(USELESS_ELVIS.on(expression, leftType));
|
context.trace.report(USELESS_ELVIS.on(expression, leftType));
|
||||||
}
|
}
|
||||||
else if (KtPsiUtil.isNullConstant(right) && leftType != null && !FlexibleTypesKt.isNullabilityFlexible(leftType)) {
|
else if (KtPsiUtil.isNullConstant(right) && leftType != null && !FlexibleTypesKt.isNullabilityFlexible(leftType)) {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// For KT-3491
|
// !DIAGNOSTICS: -UNUSED_PARAMETER, -SENSELESS_COMPARISON, -DEBUG_INFO_SMARTCAST
|
||||||
|
|
||||||
fun <T: Any?> test1(t: Any?): Any {
|
fun <T: Any?> test1(t: Any?): Any {
|
||||||
return <!UNCHECKED_CAST!>t as T<!> ?: ""
|
return <!UNCHECKED_CAST!>t as T<!> ?: ""
|
||||||
@@ -10,8 +10,35 @@ fun <T: Any> test2(t: Any?): Any {
|
|||||||
|
|
||||||
fun <T: Any?> test3(t: Any?): Any {
|
fun <T: Any?> test3(t: Any?): Any {
|
||||||
if (t != null) {
|
if (t != null) {
|
||||||
return t <!USELESS_ELVIS!>?: ""<!>
|
return t <!USELESS_ELVIS!>?: ""<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
fun takeNotNull(s: String) {}
|
||||||
|
fun <T> notNull(): T = TODO()
|
||||||
|
fun <T> nullable(): T? = null
|
||||||
|
fun <T> dependOn(x: T) = x
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
takeNotNull(notNull() <!USELESS_ELVIS!>?: ""<!>)
|
||||||
|
takeNotNull(nullable() ?: "")
|
||||||
|
|
||||||
|
val x: String? = null
|
||||||
|
takeNotNull(dependOn(x) ?: "")
|
||||||
|
takeNotNull(dependOn(dependOn(x)) ?: "")
|
||||||
|
takeNotNull(dependOn(dependOn(x as String)) <!USELESS_ELVIS!>?: ""<!>)
|
||||||
|
|
||||||
|
if (x != null) {
|
||||||
|
takeNotNull(dependOn(x) <!USELESS_ELVIS!>?: ""<!>)
|
||||||
|
takeNotNull(dependOn(dependOn(x)) <!USELESS_ELVIS!>?: ""<!>)
|
||||||
|
takeNotNull(dependOn(dependOn(x) <!USELESS_CAST!>as? String<!>) ?: "")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <reified T : Any> reifiedNull(): T? = null
|
||||||
|
|
||||||
|
fun testFrom13648() {
|
||||||
|
takeNotNull(reifiedNull() ?: "")
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,12 @@
|
|||||||
package
|
package
|
||||||
|
|
||||||
|
public fun </*0*/ T> dependOn(/*0*/ x: T): T
|
||||||
|
public fun </*0*/ T> notNull(): T
|
||||||
|
public fun </*0*/ T> nullable(): T?
|
||||||
|
public inline fun </*0*/ reified T : kotlin.Any> reifiedNull(): T?
|
||||||
|
public fun takeNotNull(/*0*/ s: kotlin.String): kotlin.Unit
|
||||||
|
public fun test(): kotlin.Unit
|
||||||
public fun </*0*/ T> test1(/*0*/ t: kotlin.Any?): kotlin.Any
|
public fun </*0*/ T> test1(/*0*/ t: kotlin.Any?): kotlin.Any
|
||||||
public fun </*0*/ T : kotlin.Any> test2(/*0*/ t: kotlin.Any?): kotlin.Any
|
public fun </*0*/ T : kotlin.Any> test2(/*0*/ t: kotlin.Any?): kotlin.Any
|
||||||
public fun </*0*/ T> test3(/*0*/ t: kotlin.Any?): kotlin.Any
|
public fun </*0*/ T> test3(/*0*/ t: kotlin.Any?): kotlin.Any
|
||||||
|
public fun testFrom13648(): kotlin.Unit
|
||||||
|
|||||||
+25
-1
@@ -1,4 +1,4 @@
|
|||||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -SENSELESS_COMPARISON
|
// !DIAGNOSTICS: -UNUSED_VARIABLE -SENSELESS_COMPARISON, -UNUSED_PARAMETER
|
||||||
|
|
||||||
// FILE: J.java
|
// FILE: J.java
|
||||||
|
|
||||||
@@ -10,6 +10,20 @@ public class J {
|
|||||||
@Nullable
|
@Nullable
|
||||||
public static J staticN;
|
public static J staticN;
|
||||||
public static J staticJ;
|
public static J staticJ;
|
||||||
|
|
||||||
|
public static <T> T getAny() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static <T> T getNNAny() {
|
||||||
|
return (T) null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static <T> T getNAny() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FILE: k.kt
|
// FILE: k.kt
|
||||||
@@ -38,5 +52,15 @@ fun test() {
|
|||||||
if (platformJ != null) {
|
if (platformJ != null) {
|
||||||
platformJ <!USELESS_ELVIS!>?: J()<!>
|
platformJ <!USELESS_ELVIS!>?: J()<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
takeNotNull(J.staticNN <!USELESS_ELVIS!>?: J()<!>)
|
||||||
|
takeNotNull(J.staticN ?: J())
|
||||||
|
takeNotNull(J.staticJ ?: J())
|
||||||
|
takeNotNull(J.getAny() ?: J())
|
||||||
|
takeNotNull(J.getNNAny() <!USELESS_ELVIS!>?: J()<!>)
|
||||||
|
takeNotNull(J.getNAny() ?: J())
|
||||||
|
|
||||||
|
val x = <!UNRESOLVED_REFERENCE!>unresolved<!> ?: null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun takeNotNull(s: J) {}
|
||||||
|
|||||||
+4
@@ -1,5 +1,6 @@
|
|||||||
package
|
package
|
||||||
|
|
||||||
|
public fun takeNotNull(/*0*/ s: J): kotlin.Unit
|
||||||
public fun test(): kotlin.Unit
|
public fun test(): kotlin.Unit
|
||||||
|
|
||||||
public open class J {
|
public open class J {
|
||||||
@@ -12,4 +13,7 @@ public open class J {
|
|||||||
public final var staticJ: J!
|
public final var staticJ: J!
|
||||||
@org.jetbrains.annotations.Nullable public final var staticN: J?
|
@org.jetbrains.annotations.Nullable public final var staticN: J?
|
||||||
@org.jetbrains.annotations.NotNull public final var staticNN: J
|
@org.jetbrains.annotations.NotNull public final var staticNN: J
|
||||||
|
public open fun </*0*/ T : kotlin.Any!> getAny(): T!
|
||||||
|
@org.jetbrains.annotations.Nullable public open fun </*0*/ T : kotlin.Any!> getNAny(): T?
|
||||||
|
@org.jetbrains.annotations.NotNull public open fun </*0*/ T : kotlin.Any!> getNNAny(): T
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user