From 90a8a164b4411b38e6ebd8f093742a51948698df Mon Sep 17 00:00:00 2001 From: Mikhail Zarechenskiy Date: Wed, 5 Apr 2017 16:37:02 +0300 Subject: [PATCH] Fix false warning about check for instance of nullable type #KT-12269 Fixed --- .../PatternMatchingTypingVisitor.kt | 4 +- .../tests/cast/IsErasedUpcastToNonReified.kt | 6 +-- .../tests/cast/checkCastToNullableType.kt | 38 +++++++++++++++++++ .../tests/cast/checkCastToNullableType.txt | 15 ++++++++ .../nullability/smartCastRefinedClass.kt | 2 +- .../checkers/DiagnosticsTestGenerated.java | 6 +++ 6 files changed, 65 insertions(+), 6 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/cast/checkCastToNullableType.kt create mode 100644 compiler/testData/diagnostics/tests/cast/checkCastToNullableType.txt diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/PatternMatchingTypingVisitor.kt b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/PatternMatchingTypingVisitor.kt index a49b9f1ef42..a5d0412094d 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/PatternMatchingTypingVisitor.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/PatternMatchingTypingVisitor.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2015 JetBrains s.r.o. + * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -433,7 +433,7 @@ class PatternMatchingTypingVisitor internal constructor(facade: ExpressionTyping context.trace.report(IS_ENUM_ENTRY.on(typeReferenceAfterIs)) } - if (!subjectType.isMarkedNullable && targetType.isMarkedNullable) { + if (!TypeUtils.isNullableType(subjectType) && targetType.isMarkedNullable) { val element = typeReferenceAfterIs.typeElement assert(element is KtNullableType) { "element must be instance of " + KtNullableType::class.java.name } context.trace.report(Errors.USELESS_NULLABLE_CHECK.on(element as KtNullableType)) diff --git a/compiler/testData/diagnostics/tests/cast/IsErasedUpcastToNonReified.kt b/compiler/testData/diagnostics/tests/cast/IsErasedUpcastToNonReified.kt index 9fae5c4ead9..78814190537 100644 --- a/compiler/testData/diagnostics/tests/cast/IsErasedUpcastToNonReified.kt +++ b/compiler/testData/diagnostics/tests/cast/IsErasedUpcastToNonReified.kt @@ -4,11 +4,11 @@ fun test(x: T?, y: S, z: T) { y is T y is S - y is T? - y is S? + y is T? + y is S? z is T - z is T? + z is T? null as T null as T? diff --git a/compiler/testData/diagnostics/tests/cast/checkCastToNullableType.kt b/compiler/testData/diagnostics/tests/cast/checkCastToNullableType.kt new file mode 100644 index 00000000000..77abb9301c3 --- /dev/null +++ b/compiler/testData/diagnostics/tests/cast/checkCastToNullableType.kt @@ -0,0 +1,38 @@ +// FILE: JavaClass.java + +import org.jetbrains.annotations.Nullable +import org.jetbrains.annotations.NotNull + +public class JavaClass { + static Integer foo() { + return 1; + } + + @Nullable + static Integer fooN() { + return 1; + } + + @NotNull + static Integer fooNN() { + return 1; + } +} + +// FILE: test.kt + +fun test(x1: T, x2: T?, y1: S, y2: S?) { + x1 is T? + x2 is T? + y1 is S? + y2 is S? + + val f1 = JavaClass.foo() + f1 is Int? + + val f2 = JavaClass.fooN() + f2 is Int? + + val f3 = JavaClass.fooNN() + f3 is Int? +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/cast/checkCastToNullableType.txt b/compiler/testData/diagnostics/tests/cast/checkCastToNullableType.txt new file mode 100644 index 00000000000..313b7c4daea --- /dev/null +++ b/compiler/testData/diagnostics/tests/cast/checkCastToNullableType.txt @@ -0,0 +1,15 @@ +package + +public fun test(/*0*/ x1: T, /*1*/ x2: T?, /*2*/ y1: S, /*3*/ y2: S?): kotlin.Unit + +public open class JavaClass { + public constructor JavaClass() + 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 + + // Static members + public/*package*/ open fun foo(): kotlin.Int! + @org.jetbrains.annotations.Nullable public/*package*/ open fun fooN(): kotlin.Int? + @org.jetbrains.annotations.NotNull public/*package*/ open fun fooNN(): kotlin.Int +} diff --git a/compiler/testData/diagnostics/tests/generics/nullability/smartCastRefinedClass.kt b/compiler/testData/diagnostics/tests/generics/nullability/smartCastRefinedClass.kt index ff76e5ca639..01dc2ac5be8 100644 --- a/compiler/testData/diagnostics/tests/generics/nullability/smartCastRefinedClass.kt +++ b/compiler/testData/diagnostics/tests/generics/nullability/smartCastRefinedClass.kt @@ -1,5 +1,5 @@ fun foo(x: T) { - if (x is String?) { + if (x is String?) { x.length if (x != null) { diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index b9669d93db0..99064b2b5dd 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -2710,6 +2710,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { doTest(fileName); } + @TestMetadata("checkCastToNullableType.kt") + public void testCheckCastToNullableType() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/cast/checkCastToNullableType.kt"); + doTest(fileName); + } + @TestMetadata("constants.kt") public void testConstants() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/cast/constants.kt");