Implement deprecation cycle for proper refinement rhs type in assignments for java fields
^KT-46727 Fixed
This commit is contained in:
+6
@@ -13764,6 +13764,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
||||
runTest("compiler/testData/diagnostics/tests/inference/capturedTypes/kt46727.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt46727Warnings.kt")
|
||||
public void testKt46727Warnings() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/capturedTypes/kt46727Warnings.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("memberScopeOfCaptured.kt")
|
||||
public void testMemberScopeOfCaptured() throws Exception {
|
||||
|
||||
+6
@@ -13764,6 +13764,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
|
||||
runTest("compiler/testData/diagnostics/tests/inference/capturedTypes/kt46727.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt46727Warnings.kt")
|
||||
public void testKt46727Warnings() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/capturedTypes/kt46727Warnings.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("memberScopeOfCaptured.kt")
|
||||
public void testMemberScopeOfCaptured() throws Exception {
|
||||
|
||||
-6
@@ -684,12 +684,6 @@ public class FirOldFrontendForeignAnnotationsCompiledJavaTestGenerated extends A
|
||||
runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/strictMode/kt47437.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt48261.kt")
|
||||
public void testKt48261() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/strictMode/kt48261.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("NonPlatformTypeParameter.kt")
|
||||
public void testNonPlatformTypeParameter() throws Exception {
|
||||
|
||||
-6
@@ -684,12 +684,6 @@ public class FirOldFrontendForeignAnnotationsCompiledJavaWithPsiClassReadingTest
|
||||
runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/strictMode/kt47437.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt48261.kt")
|
||||
public void testKt48261() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/strictMode/kt48261.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("NonPlatformTypeParameter.kt")
|
||||
public void testNonPlatformTypeParameter() throws Exception {
|
||||
|
||||
-6
@@ -684,12 +684,6 @@ public class FirOldFrontendForeignAnnotationsSourceJavaTestGenerated extends Abs
|
||||
runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/strictMode/kt47437.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt48261.kt")
|
||||
public void testKt48261() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/strictMode/kt48261.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("NonPlatformTypeParameter.kt")
|
||||
public void testNonPlatformTypeParameter() throws Exception {
|
||||
|
||||
+78
-2
@@ -35,6 +35,7 @@ import org.jetbrains.kotlin.resolve.calls.ArgumentTypeResolver;
|
||||
import org.jetbrains.kotlin.resolve.calls.checkers.NewSchemeOfIntegerOperatorResolutionChecker;
|
||||
import org.jetbrains.kotlin.resolve.calls.context.CallPosition;
|
||||
import org.jetbrains.kotlin.resolve.calls.context.ContextDependency;
|
||||
import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext;
|
||||
import org.jetbrains.kotlin.resolve.calls.context.TemporaryTraceAndCache;
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.BuilderInferenceSession;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
||||
@@ -335,7 +336,15 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
|
||||
}
|
||||
KotlinTypeInfo rightInfo = facade.getTypeInfo(rightOperand, context.replaceDataFlowInfo(leftInfo.getDataFlowInfo()));
|
||||
|
||||
KotlinType expectedType = refineTypeFromPropertySetterIfPossible(context.trace.getBindingContext(), leftOperand, leftInfo.getType());
|
||||
boolean refineJavaFieldInTypeProperly =
|
||||
components.languageVersionSettings.supportsFeature(LanguageFeature.RefineTypeCheckingOnAssignmentsToJavaFields);
|
||||
|
||||
BindingContext bindingContext = context.trace.getBindingContext();
|
||||
KotlinType leftType = leftInfo.getType();
|
||||
|
||||
KotlinType expectedType = refineJavaFieldInTypeProperly
|
||||
? refineTypeByPropertyInType(bindingContext, leftOperand, leftType)
|
||||
: refineTypeFromPropertySetterIfPossible(bindingContext, leftOperand, leftType);
|
||||
|
||||
Ref<Boolean> hasErrorsOnTypeChecking = Ref.create(false);
|
||||
components.dataFlowAnalyzer.checkType(
|
||||
@@ -349,6 +358,12 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
|
||||
);
|
||||
basic.checkLValue(context.trace, context, leftOperand, rightOperand, expression, false);
|
||||
|
||||
if (!refineJavaFieldInTypeProperly) {
|
||||
checkPropertyInTypeWithWarnings(
|
||||
context, expression, binaryOperationType, rightInfo.getDataFlowInfo(), leftOperand, leftType, expectedType
|
||||
);
|
||||
}
|
||||
|
||||
return !hasErrorsOnTypeChecking.get() ? rightInfo : null;
|
||||
}
|
||||
|
||||
@@ -370,6 +385,22 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
|
||||
) {
|
||||
VariableDescriptor descriptor = BindingContextUtils.extractVariableFromResolvedCall(bindingContext, leftOperand);
|
||||
|
||||
if (descriptor instanceof PropertyDescriptor) {
|
||||
PropertySetterDescriptor setter = ((PropertyDescriptor) descriptor).getSetter();
|
||||
if (setter != null) return setter.getValueParameters().get(0).getType();
|
||||
}
|
||||
|
||||
return leftOperandType;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static KotlinType refineTypeByPropertyInType(
|
||||
@NotNull BindingContext bindingContext,
|
||||
@Nullable KtElement leftOperand,
|
||||
@Nullable KotlinType leftOperandType
|
||||
) {
|
||||
VariableDescriptor descriptor = BindingContextUtils.extractVariableFromResolvedCall(bindingContext, leftOperand);
|
||||
|
||||
if (descriptor instanceof PropertyDescriptor) {
|
||||
KotlinType inType = ((PropertyDescriptor) descriptor).getInType();
|
||||
if (inType != null) return inType;
|
||||
@@ -400,7 +431,16 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
|
||||
context.replaceCallPosition(new CallPosition.PropertyAssignment(left, true)),
|
||||
facade
|
||||
);
|
||||
KotlinType expectedType = refineTypeFromPropertySetterIfPossible(context.trace.getBindingContext(), leftOperand, leftInfo.getType());
|
||||
|
||||
BindingContext bindingContext = context.trace.getBindingContext();
|
||||
KotlinType leftType = leftInfo.getType();
|
||||
|
||||
boolean refineJavaFieldInTypeProperly =
|
||||
components.languageVersionSettings.supportsFeature(LanguageFeature.RefineTypeCheckingOnAssignmentsToJavaFields);
|
||||
KotlinType expectedType = refineJavaFieldInTypeProperly
|
||||
? refineTypeByPropertyInType(bindingContext, leftOperand, leftType)
|
||||
: refineTypeFromPropertySetterIfPossible(bindingContext, leftOperand, leftType);
|
||||
|
||||
DataFlowInfo dataFlowInfo = leftInfo.getDataFlowInfo();
|
||||
KotlinTypeInfo resultInfo;
|
||||
if (right != null) {
|
||||
@@ -427,9 +467,45 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
|
||||
if (expectedType != null && leftOperand != null) { //if expectedType == null, some other error has been generated
|
||||
basic.checkLValue(context.trace, context, leftOperand, right, expression, false);
|
||||
}
|
||||
|
||||
if (!refineJavaFieldInTypeProperly) {
|
||||
checkPropertyInTypeWithWarnings(
|
||||
context, expression, resultInfo.getType(), resultInfo.getDataFlowInfo(), leftOperand, leftType, expectedType
|
||||
);
|
||||
}
|
||||
|
||||
return resultInfo.replaceType(components.dataFlowAnalyzer.checkStatementType(expression, contextWithExpectedType));
|
||||
}
|
||||
|
||||
private void checkPropertyInTypeWithWarnings(
|
||||
@NotNull ResolutionContext<?> context,
|
||||
@NotNull KtBinaryExpression expression,
|
||||
@Nullable KotlinType rhsType,
|
||||
@NotNull DataFlowInfo rhsDataFlowInfo,
|
||||
@Nullable KtExpression lhsOperand,
|
||||
@Nullable KotlinType lhsType,
|
||||
@Nullable KotlinType expectedType
|
||||
) {
|
||||
if (rhsType == null || expectedType == null) return;
|
||||
|
||||
KotlinType expectedTypeByInType = refineTypeByPropertyInType(context.trace.getBindingContext(), lhsOperand, lhsType);
|
||||
|
||||
if (expectedTypeByInType != null && expectedType != expectedTypeByInType && !TypeUtils.equalTypes(expectedType, expectedTypeByInType)) {
|
||||
Ref<Boolean> hasErrorsOnTypeChecking = Ref.create(false);
|
||||
components.dataFlowAnalyzer.checkType(
|
||||
rhsType,
|
||||
expression,
|
||||
context.replaceExpectedType(expectedTypeByInType)
|
||||
.replaceDataFlowInfo(rhsDataFlowInfo)
|
||||
.replaceCallPosition(new CallPosition.PropertyAssignment(lhsOperand, false)),
|
||||
hasErrorsOnTypeChecking,
|
||||
false
|
||||
);
|
||||
if (hasErrorsOnTypeChecking.get()) {
|
||||
context.trace.report(TYPE_MISMATCH_WARNING.on(expression, expectedTypeByInType, rhsType));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public KotlinTypeInfo visitExpression(@NotNull KtExpression expression, ExpressionTypingContext context) {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// !LANGUAGE: +RefineTypeCheckingOnAssignmentsToJavaFields
|
||||
// WITH_RUNTIME
|
||||
|
||||
// FILE: Foo.java
|
||||
@@ -25,6 +26,7 @@ public class Foo3<T> {
|
||||
|
||||
fun takeStarFoo(x: Foo<*>) {
|
||||
x.value = <!ASSIGNMENT_TYPE_MISMATCH!>"test"<!>
|
||||
x.value <!NONE_APPLICABLE!>+=<!> "test"
|
||||
}
|
||||
|
||||
fun main1() {
|
||||
@@ -42,6 +44,7 @@ public class Bar<T> {
|
||||
|
||||
fun takeStarBar(x: Bar<*>) {
|
||||
<!SETTER_PROJECTED_OUT!>x.value<!> = "test"
|
||||
x.value <!UNRESOLVED_REFERENCE!>+=<!> "test"
|
||||
}
|
||||
|
||||
fun main2() {
|
||||
@@ -55,6 +58,7 @@ fun main2() {
|
||||
|
||||
fun takeStarFoo2(x: Foo2<*>) {
|
||||
x.value = <!ASSIGNMENT_TYPE_MISMATCH!>"test"<!>
|
||||
x.value <!UNRESOLVED_REFERENCE!>+=<!> "test"
|
||||
}
|
||||
|
||||
fun main3() {
|
||||
@@ -71,6 +75,7 @@ public class Bar2<T> {
|
||||
|
||||
fun takeStarBar2(x: Bar2<*>) {
|
||||
<!SETTER_PROJECTED_OUT!>x.value<!> = "test"
|
||||
x.value <!UNRESOLVED_REFERENCE!>+=<!> "test"
|
||||
}
|
||||
|
||||
fun main4() {
|
||||
@@ -84,6 +89,7 @@ fun main4() {
|
||||
|
||||
fun takeStarFoo3(x: Foo3<*>) {
|
||||
x.value = <!ASSIGNMENT_TYPE_MISMATCH!>"test"<!>
|
||||
x.value <!NONE_APPLICABLE!>+=<!> "test"
|
||||
}
|
||||
|
||||
fun main5() {
|
||||
@@ -101,6 +107,7 @@ class Bar3<T> {
|
||||
|
||||
fun takeStarBar3(x: Bar3<*>) {
|
||||
<!SETTER_PROJECTED_OUT!>x.value<!> = "test"
|
||||
x.value <!UNRESOLVED_REFERENCE!>+=<!> "test"
|
||||
}
|
||||
|
||||
fun main6() {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// !LANGUAGE: +RefineTypeCheckingOnAssignmentsToJavaFields
|
||||
// WITH_RUNTIME
|
||||
|
||||
// FILE: Foo.java
|
||||
@@ -25,6 +26,7 @@ public class Foo3<T> {
|
||||
|
||||
fun takeStarFoo(x: Foo<*>) {
|
||||
x.value = <!TYPE_MISMATCH("Nothing!; String")!>"test"<!>
|
||||
x.value <!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>+=<!> "test"
|
||||
}
|
||||
|
||||
fun main1() {
|
||||
@@ -42,6 +44,7 @@ public class Bar<T> {
|
||||
|
||||
fun takeStarBar(x: Bar<*>) {
|
||||
<!SETTER_PROJECTED_OUT!>x.value<!> = "test"
|
||||
x.value <!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>+=<!> "test"
|
||||
}
|
||||
|
||||
fun main2() {
|
||||
@@ -55,6 +58,7 @@ fun main2() {
|
||||
|
||||
fun takeStarFoo2(x: Foo2<*>) {
|
||||
x.value = <!TYPE_MISMATCH("Nothing?; String")!>"test"<!>
|
||||
x.value <!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>+=<!> "test"
|
||||
}
|
||||
|
||||
fun main3() {
|
||||
@@ -71,6 +75,7 @@ public class Bar2<T> {
|
||||
|
||||
fun takeStarBar2(x: Bar2<*>) {
|
||||
x.value = <!TYPE_MISMATCH_DUE_TO_TYPE_PROJECTIONS("Nothing?; String; Bar2<CapturedType(*)>; public final var value: T? defined in Bar2")!>"test"<!>
|
||||
x.value <!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>+=<!> "test"
|
||||
}
|
||||
|
||||
fun main4() {
|
||||
@@ -84,6 +89,7 @@ fun main4() {
|
||||
|
||||
fun takeStarFoo3(x: Foo3<*>) {
|
||||
x.value = <!TYPE_MISMATCH("Nothing; String")!>"test"<!>
|
||||
x.value <!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>+=<!> "test"
|
||||
}
|
||||
|
||||
fun main5() {
|
||||
@@ -101,6 +107,7 @@ class Bar3<T> {
|
||||
|
||||
fun takeStarBar3(x: Bar3<*>) {
|
||||
x.value = <!TYPE_MISMATCH_DUE_TO_TYPE_PROJECTIONS("Nothing?; String; Bar3<CapturedType(*)>; public final var value: T? defined in Bar3")!>"test"<!>
|
||||
x.value <!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>+=<!> "test"
|
||||
}
|
||||
|
||||
fun main6() {
|
||||
|
||||
@@ -5,8 +5,10 @@ public fun main2(): kotlin.Unit
|
||||
public fun main3(): kotlin.Unit
|
||||
public fun main4(): kotlin.Unit
|
||||
public fun main5(): kotlin.Unit
|
||||
public fun main6(): kotlin.Unit
|
||||
public fun takeStarBar(/*0*/ x: Bar<*>): kotlin.Unit
|
||||
public fun takeStarBar2(/*0*/ x: Bar2<*>): kotlin.Unit
|
||||
public fun takeStarBar3(/*0*/ x: Bar3<*>): kotlin.Unit
|
||||
public fun takeStarFoo(/*0*/ x: Foo<*>): kotlin.Unit
|
||||
public fun takeStarFoo2(/*0*/ x: Foo2<*>): kotlin.Unit
|
||||
public fun takeStarFoo3(/*0*/ x: Foo3<*>): kotlin.Unit
|
||||
@@ -27,6 +29,14 @@ public final class Bar2</*0*/ T> {
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class Bar3</*0*/ T> {
|
||||
public constructor Bar3</*0*/ T>()
|
||||
@field:kotlin.jvm.JvmField public final var value: T?
|
||||
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 Foo</*0*/ T : kotlin.Any!> {
|
||||
public constructor Foo</*0*/ T : kotlin.Any!>()
|
||||
public final var value: T!
|
||||
@@ -45,7 +55,7 @@ public open class Foo2</*0*/ T : kotlin.Any!> {
|
||||
|
||||
public open class Foo3</*0*/ T : kotlin.Any!> {
|
||||
public constructor Foo3</*0*/ T : kotlin.Any!>()
|
||||
@org.jetbrains.annotations.Nullable public final var value: T?
|
||||
@org.jetbrains.annotations.NotNull public final var value: T
|
||||
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
|
||||
|
||||
+118
@@ -0,0 +1,118 @@
|
||||
// !LANGUAGE: -RefineTypeCheckingOnAssignmentsToJavaFields
|
||||
// WITH_RUNTIME
|
||||
|
||||
// FILE: Foo.java
|
||||
public class Foo<T> {
|
||||
public T value;
|
||||
}
|
||||
|
||||
// FILE: Foo2.java
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class Foo2<T> {
|
||||
public @Nullable T value;
|
||||
}
|
||||
|
||||
// FILE: Foo3.java
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class Foo3<T> {
|
||||
public @NotNull T value;
|
||||
}
|
||||
|
||||
// FILE: main.kt
|
||||
|
||||
// --- from Java --- //
|
||||
|
||||
fun takeStarFoo(x: Foo<*>) {
|
||||
x.value = <!ASSIGNMENT_TYPE_MISMATCH!>"test"<!>
|
||||
x.value <!NONE_APPLICABLE!>+=<!> "test"
|
||||
}
|
||||
|
||||
fun main1() {
|
||||
val foo = Foo<Int>()
|
||||
foo.value = 1
|
||||
takeStarFoo(foo)
|
||||
println(foo.value) // CCE: String cannot be cast to Number
|
||||
}
|
||||
|
||||
// --- from Kotlin --- //
|
||||
|
||||
public class Bar<T> {
|
||||
var value: T = null as T
|
||||
}
|
||||
|
||||
fun takeStarBar(x: Bar<*>) {
|
||||
<!SETTER_PROJECTED_OUT!>x.value<!> = "test"
|
||||
x.value <!UNRESOLVED_REFERENCE!>+=<!> "test"
|
||||
}
|
||||
|
||||
fun main2() {
|
||||
val bar = Bar<Int>()
|
||||
bar.value = 1
|
||||
takeStarBar(bar)
|
||||
println(bar.value) // CCE: String cannot be cast to Number
|
||||
}
|
||||
|
||||
// --- from Java (nullable) --- //
|
||||
|
||||
fun takeStarFoo2(x: Foo2<*>) {
|
||||
x.value = <!ASSIGNMENT_TYPE_MISMATCH!>"test"<!>
|
||||
x.value <!UNRESOLVED_REFERENCE!>+=<!> "test"
|
||||
}
|
||||
|
||||
fun main3() {
|
||||
val foo = Foo2<Int>()
|
||||
foo.value = 1
|
||||
takeStarFoo2(foo)
|
||||
println(foo.value) // CCE: String cannot be cast to Number
|
||||
}
|
||||
|
||||
// --- from Kotlin (nullable) --- //
|
||||
public class Bar2<T> {
|
||||
var value: T? = null
|
||||
}
|
||||
|
||||
fun takeStarBar2(x: Bar2<*>) {
|
||||
<!SETTER_PROJECTED_OUT!>x.value<!> = "test"
|
||||
x.value <!UNRESOLVED_REFERENCE!>+=<!> "test"
|
||||
}
|
||||
|
||||
fun main4() {
|
||||
val bar = Bar2<Int>()
|
||||
bar.value = 1
|
||||
takeStarBar2(bar)
|
||||
println(bar.value) // CCE: String cannot be cast to Number
|
||||
}
|
||||
|
||||
// --- from Java (not-null) --- //
|
||||
|
||||
fun takeStarFoo3(x: Foo3<*>) {
|
||||
x.value = <!ASSIGNMENT_TYPE_MISMATCH!>"test"<!>
|
||||
x.value <!NONE_APPLICABLE!>+=<!> "test"
|
||||
}
|
||||
|
||||
fun main5() {
|
||||
val foo = Foo3<Int>()
|
||||
foo.value = 1
|
||||
takeStarFoo3(foo)
|
||||
println(foo.value) // CCE: String cannot be cast to Number
|
||||
}
|
||||
|
||||
// --- from Kotlin (field) --- //
|
||||
class Bar3<T> {
|
||||
@JvmField
|
||||
var value: T? = null
|
||||
}
|
||||
|
||||
fun takeStarBar3(x: Bar3<*>) {
|
||||
<!SETTER_PROJECTED_OUT!>x.value<!> = "test"
|
||||
x.value <!UNRESOLVED_REFERENCE!>+=<!> "test"
|
||||
}
|
||||
|
||||
fun main6() {
|
||||
val bar = Bar3<Int>()
|
||||
bar.value = 1
|
||||
takeStarBar3(bar)
|
||||
println(bar.value) // CCE: String cannot be cast to Number
|
||||
}
|
||||
+118
@@ -0,0 +1,118 @@
|
||||
// !LANGUAGE: -RefineTypeCheckingOnAssignmentsToJavaFields
|
||||
// WITH_RUNTIME
|
||||
|
||||
// FILE: Foo.java
|
||||
public class Foo<T> {
|
||||
public T value;
|
||||
}
|
||||
|
||||
// FILE: Foo2.java
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class Foo2<T> {
|
||||
public @Nullable T value;
|
||||
}
|
||||
|
||||
// FILE: Foo3.java
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class Foo3<T> {
|
||||
public @NotNull T value;
|
||||
}
|
||||
|
||||
// FILE: main.kt
|
||||
|
||||
// --- from Java --- //
|
||||
|
||||
fun takeStarFoo(x: Foo<*>) {
|
||||
<!TYPE_MISMATCH_WARNING("Nothing!; String")!>x.value = "test"<!>
|
||||
<!TYPE_MISMATCH_WARNING("Nothing!; String")!><!SMARTCAST_IMPOSSIBLE!>x.value<!> += "test"<!>
|
||||
}
|
||||
|
||||
fun main1() {
|
||||
val foo = Foo<Int>()
|
||||
foo.value = 1
|
||||
takeStarFoo(foo)
|
||||
println(foo.value) // CCE: String cannot be cast to Number
|
||||
}
|
||||
|
||||
// --- from Kotlin --- //
|
||||
|
||||
public class Bar<T> {
|
||||
var value: T = null <!UNCHECKED_CAST!>as T<!>
|
||||
}
|
||||
|
||||
fun takeStarBar(x: Bar<*>) {
|
||||
<!SETTER_PROJECTED_OUT!>x.value<!> = "test"
|
||||
x.value <!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>+=<!> "test"
|
||||
}
|
||||
|
||||
fun main2() {
|
||||
val bar = Bar<Int>()
|
||||
bar.value = 1
|
||||
takeStarBar(bar)
|
||||
println(bar.value) // CCE: String cannot be cast to Number
|
||||
}
|
||||
|
||||
// --- from Java (nullable) --- //
|
||||
|
||||
fun takeStarFoo2(x: Foo2<*>) {
|
||||
<!TYPE_MISMATCH_WARNING("Nothing?; String")!>x.value = "test"<!>
|
||||
<!TYPE_MISMATCH_WARNING("Nothing?; String")!><!SMARTCAST_IMPOSSIBLE!>x.value<!> += "test"<!>
|
||||
}
|
||||
|
||||
fun main3() {
|
||||
val foo = Foo2<Int>()
|
||||
foo.value = 1
|
||||
takeStarFoo2(foo)
|
||||
println(foo.value) // CCE: String cannot be cast to Number
|
||||
}
|
||||
|
||||
// --- from Kotlin (nullable) --- //
|
||||
public class Bar2<T> {
|
||||
var value: T? = null
|
||||
}
|
||||
|
||||
fun takeStarBar2(x: Bar2<*>) {
|
||||
x.value = <!TYPE_MISMATCH_DUE_TO_TYPE_PROJECTIONS("Nothing?; String; Bar2<CapturedType(*)>; public final var value: T? defined in Bar2")!>"test"<!>
|
||||
x.value <!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>+=<!> "test"
|
||||
}
|
||||
|
||||
fun main4() {
|
||||
val bar = Bar2<Int>()
|
||||
bar.value = 1
|
||||
takeStarBar2(bar)
|
||||
println(bar.value) // CCE: String cannot be cast to Number
|
||||
}
|
||||
|
||||
// --- from Java (not-null) --- //
|
||||
|
||||
fun takeStarFoo3(x: Foo3<*>) {
|
||||
<!TYPE_MISMATCH_WARNING("Nothing; String")!>x.value = "test"<!>
|
||||
<!TYPE_MISMATCH_WARNING("Nothing; String")!><!SMARTCAST_IMPOSSIBLE!>x.value<!> += "test"<!>
|
||||
}
|
||||
|
||||
fun main5() {
|
||||
val foo = Foo3<Int>()
|
||||
foo.value = 1
|
||||
takeStarFoo3(foo)
|
||||
println(foo.value) // CCE: String cannot be cast to Number
|
||||
}
|
||||
|
||||
// --- from Kotlin (field) --- //
|
||||
class Bar3<T> {
|
||||
@JvmField
|
||||
var value: T? = null
|
||||
}
|
||||
|
||||
fun takeStarBar3(x: Bar3<*>) {
|
||||
x.value = <!TYPE_MISMATCH_DUE_TO_TYPE_PROJECTIONS("Nothing?; String; Bar3<CapturedType(*)>; public final var value: T? defined in Bar3")!>"test"<!>
|
||||
x.value <!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>+=<!> "test"
|
||||
}
|
||||
|
||||
fun main6() {
|
||||
val bar = Bar3<Int>()
|
||||
bar.value = 1
|
||||
takeStarBar3(bar)
|
||||
println(bar.value) // CCE: String cannot be cast to Number
|
||||
}
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
package
|
||||
|
||||
public fun main1(): kotlin.Unit
|
||||
public fun main2(): kotlin.Unit
|
||||
public fun main3(): kotlin.Unit
|
||||
public fun main4(): kotlin.Unit
|
||||
public fun main5(): kotlin.Unit
|
||||
public fun main6(): kotlin.Unit
|
||||
public fun takeStarBar(/*0*/ x: Bar<*>): kotlin.Unit
|
||||
public fun takeStarBar2(/*0*/ x: Bar2<*>): kotlin.Unit
|
||||
public fun takeStarBar3(/*0*/ x: Bar3<*>): kotlin.Unit
|
||||
public fun takeStarFoo(/*0*/ x: Foo<*>): kotlin.Unit
|
||||
public fun takeStarFoo2(/*0*/ x: Foo2<*>): kotlin.Unit
|
||||
public fun takeStarFoo3(/*0*/ x: Foo3<*>): kotlin.Unit
|
||||
|
||||
public final class Bar</*0*/ T> {
|
||||
public constructor Bar</*0*/ T>()
|
||||
public final var value: T
|
||||
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 Bar2</*0*/ T> {
|
||||
public constructor Bar2</*0*/ T>()
|
||||
public final var value: T?
|
||||
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 Bar3</*0*/ T> {
|
||||
public constructor Bar3</*0*/ T>()
|
||||
@field:kotlin.jvm.JvmField public final var value: T?
|
||||
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 Foo</*0*/ T : kotlin.Any!> {
|
||||
public constructor Foo</*0*/ T : kotlin.Any!>()
|
||||
public final var value: T!
|
||||
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 Foo2</*0*/ T : kotlin.Any!> {
|
||||
public constructor Foo2</*0*/ T : kotlin.Any!>()
|
||||
@org.jetbrains.annotations.Nullable public final var value: T?
|
||||
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 Foo3</*0*/ T : kotlin.Any!> {
|
||||
public constructor Foo3</*0*/ T : kotlin.Any!>()
|
||||
@org.jetbrains.annotations.NotNull public final var value: T
|
||||
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
|
||||
}
|
||||
Generated
+6
@@ -13770,6 +13770,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/capturedTypes/kt46727.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt46727Warnings.kt")
|
||||
public void testKt46727Warnings() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/capturedTypes/kt46727Warnings.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("memberScopeOfCaptured.kt")
|
||||
public void testMemberScopeOfCaptured() throws Exception {
|
||||
|
||||
-6
@@ -684,12 +684,6 @@ public class ForeignAnnotationsCompiledJavaTestGenerated extends AbstractForeign
|
||||
runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/strictMode/kt47437.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt48261.kt")
|
||||
public void testKt48261() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/strictMode/kt48261.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("NonPlatformTypeParameter.kt")
|
||||
public void testNonPlatformTypeParameter() throws Exception {
|
||||
|
||||
-6
@@ -684,12 +684,6 @@ public class ForeignAnnotationsCompiledJavaWithPsiClassReadingTestGenerated exte
|
||||
runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/strictMode/kt47437.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt48261.kt")
|
||||
public void testKt48261() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/strictMode/kt48261.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("NonPlatformTypeParameter.kt")
|
||||
public void testNonPlatformTypeParameter() throws Exception {
|
||||
|
||||
-6
@@ -684,12 +684,6 @@ public class ForeignAnnotationsSourceJavaTestGenerated extends AbstractForeignAn
|
||||
runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/strictMode/kt47437.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt48261.kt")
|
||||
public void testKt48261() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/strictMode/kt48261.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("NonPlatformTypeParameter.kt")
|
||||
public void testNonPlatformTypeParameter() throws Exception {
|
||||
|
||||
@@ -231,6 +231,7 @@ enum class LanguageFeature(
|
||||
SafeCallsAreAlwaysNullable(KOTLIN_1_7),
|
||||
StopPropagatingDeprecationThroughOverrides(KOTLIN_1_7),
|
||||
AbstractClassMemberNotImplementedWithIntermediateAbstractClass(KOTLIN_1_7, kind = BUG_FIX),
|
||||
RefineTypeCheckingOnAssignmentsToJavaFields(KOTLIN_1_7),
|
||||
|
||||
// Temporarily disabled, see KT-27084/KT-22379
|
||||
SoundSmartcastFromLoopConditionForLoopAssignedVariables(sinceVersion = null, kind = BUG_FIX),
|
||||
|
||||
Reference in New Issue
Block a user