diff --git a/compiler/fir/resolve/testData/resolve/arguments/lambdaInLambda2.kt b/compiler/fir/resolve/testData/resolve/arguments/lambdaInLambda2.kt index d4663c93e87..cdd9f324543 100644 --- a/compiler/fir/resolve/testData/resolve/arguments/lambdaInLambda2.kt +++ b/compiler/fir/resolve/testData/resolve/arguments/lambdaInLambda2.kt @@ -20,7 +20,7 @@ interface PsiMethod { interface PsiClass fun test() { - val processor = AdapterProcessor( + val processor = AdapterProcessor( Function { method: PsiMethod? -> method?.containingClass } ) } \ No newline at end of file diff --git a/compiler/fir/resolve/testData/resolve/arguments/lambdaInLambda2.txt b/compiler/fir/resolve/testData/resolve/arguments/lambdaInLambda2.txt index cdbb4211467..dba553295ee 100644 --- a/compiler/fir/resolve/testData/resolve/arguments/lambdaInLambda2.txt +++ b/compiler/fir/resolve/testData/resolve/arguments/lambdaInLambda2.txt @@ -7,7 +7,7 @@ FILE: main.kt public abstract interface PsiClass : R|kotlin/Any| { } public final fun test(): R|kotlin/Unit| { - lval processor: R|AdapterProcessor| = R|/AdapterProcessor.AdapterProcessor|(R|/Function|!|>( = Function@fun (method: R|PsiMethod?|): R|PsiClass?| { + lval processor: R|AdapterProcessor| = R|/AdapterProcessor.AdapterProcessor|(R|/Function|( = Function@fun (method: R|PsiMethod?|): R|PsiClass?| { R|/method|?.R|/PsiMethod.containingClass| } )) diff --git a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsSmokeTestGenerated.java b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsSmokeTestGenerated.java index 396a86956b5..e5b291c273b 100644 --- a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsSmokeTestGenerated.java +++ b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsSmokeTestGenerated.java @@ -14635,6 +14635,11 @@ public class FirDiagnosticsSmokeTestGenerated extends AbstractFirDiagnosticsSmok runTest("compiler/testData/diagnostics/tests/nullableTypes/elvisOnUnit.kt"); } + @TestMetadata("inferenceFlexibleTToNullable.kt") + public void testInferenceFlexibleTToNullable() throws Exception { + runTest("compiler/testData/diagnostics/tests/nullableTypes/inferenceFlexibleTToNullable.kt"); + } + @TestMetadata("nullAssertOnTypeWithNullableUpperBound.kt") public void testNullAssertOnTypeWithNullableUpperBound() throws Exception { runTest("compiler/testData/diagnostics/tests/nullableTypes/nullAssertOnTypeWithNullableUpperBound.kt"); diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/AbstractTypeCheckerContextForConstraintSystem.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/AbstractTypeCheckerContextForConstraintSystem.kt index 287e2509ea5..460870336cb 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/AbstractTypeCheckerContextForConstraintSystem.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/AbstractTypeCheckerContextForConstraintSystem.kt @@ -136,7 +136,7 @@ abstract class AbstractTypeCheckerContextForConstraintSystem : AbstractTypeCheck * * => Foo <: T! -- (Foo!! .. Foo) <: T * - * Foo? <: T! -- (Foo!! .. Foo?) <: T + * Foo? <: T! -- Foo? <: T * * * (Foo..Bar) <: T! -- @@ -163,7 +163,11 @@ abstract class AbstractTypeCheckerContextForConstraintSystem : AbstractTypeCheck when (subType) { is SimpleTypeMarker -> // Foo <: T! -- (Foo!! .. Foo) <: T - createFlexibleType(subType.makeSimpleTypeDefinitelyNotNullOrNotNull(), subType) + if (subType.isNullableType()) { + subType // prefer nullable type to flexible one: `Foo? <: (T..T?)` => lowerConstraint = `Foo?` + } else { + createFlexibleType(subType.makeSimpleTypeDefinitelyNotNullOrNotNull(), subType) + } is FlexibleTypeMarker -> // (Foo..Bar) <: T! -- (Foo!! .. Bar) <: T diff --git a/compiler/testData/codegen/box/platformTypes/inferenceFlexibleTToNullable.kt b/compiler/testData/codegen/box/platformTypes/inferenceFlexibleTToNullable.kt new file mode 100644 index 00000000000..075cc1b7b57 --- /dev/null +++ b/compiler/testData/codegen/box/platformTypes/inferenceFlexibleTToNullable.kt @@ -0,0 +1,71 @@ +// !LANGUAGE: +NewInference + +// FILE: Foo.java +import org.jetbrains.annotations.NotNull; + +public class Foo { + T x; + + public Foo(T x) { + this.x = x; + } + + public static Number bar() { return null; } + + public static K simpleId(K k) { + return k; + } + + public T produceT() { + return x; + } + + @NotNull + public T produceNotNullT() { + return x; + } + + public void consumeT(T x) {} +} + +// FILE: main.kt +fun bar(n: Number?, d: T, e: T) { + val b: Number? = Foo.simpleId(n) + b?.toInt() + val c = Foo.simpleId(n) + c?.toInt() + + val x4 = Foo(if (true) 10 else null) + val x6: Number? = x4.produceT() + x6?.toInt() + val x7 = x4.produceT() + x7?.toInt() + val x8 = x4.produceNotNullT() + x8.toInt() + + x4.consumeT(x7) + + val x9: T = Foo.simpleId(d) + val x10: T? = Foo.simpleId(d) + + if (e != null) { + var x11 = e + x11 = Foo.simpleId(d) // assign to definitely not-null T, the lack an error is consistent with old inference + } + + var x11 = Foo(e).x + x11 = Foo.simpleId(d) // assign to flexible T + + var x12 = Foo.bar() + x12 = Foo.simpleId(n) // assign to flexible Number + x12.toInt() + + var x13 = e + x13 = Foo.simpleId(d) +} + +fun box(): String { + bar(10, "", "") + + return "OK" +} diff --git a/compiler/testData/diagnostics/tests/nullableTypes/inferenceFlexibleTToNullable.kt b/compiler/testData/diagnostics/tests/nullableTypes/inferenceFlexibleTToNullable.kt new file mode 100644 index 00000000000..f2a92675d91 --- /dev/null +++ b/compiler/testData/diagnostics/tests/nullableTypes/inferenceFlexibleTToNullable.kt @@ -0,0 +1,63 @@ +// !DIAGNOSTICS: -UNUSED_VARIABLE -UNCHECKED_CAST -UNUSED_VALUE -ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE +// !LANGUAGE: +NewInference +// SKIP_TXT + +// FILE: Foo.java +import org.jetbrains.annotations.NotNull; + +public class Foo { + T x; + + public Foo(T x) { + this.x = x; + } + + public static Number bar() { return null; } + + public static K simpleId(K k) { + return k; + } + + public T produceT() { + return x; + } + + @NotNull + public T produceNotNullT() { + return x; + } + + public void consumeT(T x) {} +} + +// FILE: main.kt +fun bar(n: Number?, d: T, e: T) { + val a: Number = Foo.simpleId(n) + val b: Number? = Foo.simpleId(n) + val c = Foo.simpleId(n) + + val x4 = Foo(if (true) 10 else null) + val x5: Number = x4.produceT() + val x6: Number? = x4.produceT() + val x7 = x4.produceT() + val x8 = x4.produceNotNullT() + + x4.consumeT(x7) + + val x9: T = Foo.simpleId(d) + val x10: T? = Foo.simpleId(d) + + if (e != null) { + var x11 = e + x11 = Foo.simpleId(d) // assign to definitely not-null T, the lack an error is consistent with old inference + } + + var x11 = Foo(null as T).x + x11 = Foo.simpleId(d) // assign to flexible T + + var x12 = Foo.bar() + x12 = Foo.simpleId(n) // assign to flexible Number + + var x13 = e + x13 = Foo.simpleId(d) +} diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index 899d43083eb..77fa1030748 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -14642,6 +14642,11 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { runTest("compiler/testData/diagnostics/tests/nullableTypes/elvisOnUnit.kt"); } + @TestMetadata("inferenceFlexibleTToNullable.kt") + public void testInferenceFlexibleTToNullable() throws Exception { + runTest("compiler/testData/diagnostics/tests/nullableTypes/inferenceFlexibleTToNullable.kt"); + } + @TestMetadata("nullAssertOnTypeWithNullableUpperBound.kt") public void testNullAssertOnTypeWithNullableUpperBound() throws Exception { runTest("compiler/testData/diagnostics/tests/nullableTypes/nullAssertOnTypeWithNullableUpperBound.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java index be712a8a42d..a3d0f8a6efc 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java @@ -14637,6 +14637,11 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing runTest("compiler/testData/diagnostics/tests/nullableTypes/elvisOnUnit.kt"); } + @TestMetadata("inferenceFlexibleTToNullable.kt") + public void testInferenceFlexibleTToNullable() throws Exception { + runTest("compiler/testData/diagnostics/tests/nullableTypes/inferenceFlexibleTToNullable.kt"); + } + @TestMetadata("nullAssertOnTypeWithNullableUpperBound.kt") public void testNullAssertOnTypeWithNullableUpperBound() throws Exception { runTest("compiler/testData/diagnostics/tests/nullableTypes/nullAssertOnTypeWithNullableUpperBound.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 6f5c0c689fe..8b278797cfd 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -18111,6 +18111,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/platformTypes"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); } + @TestMetadata("inferenceFlexibleTToNullable.kt") + public void testInferenceFlexibleTToNullable() throws Exception { + runTest("compiler/testData/codegen/box/platformTypes/inferenceFlexibleTToNullable.kt"); + } + @TestMetadata("unsafeNullCheck.kt") public void testUnsafeNullCheck() throws Exception { runTest("compiler/testData/codegen/box/platformTypes/unsafeNullCheck.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index da486c67a36..0caf5655d06 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -18111,6 +18111,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/platformTypes"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); } + @TestMetadata("inferenceFlexibleTToNullable.kt") + public void testInferenceFlexibleTToNullable() throws Exception { + runTest("compiler/testData/codegen/box/platformTypes/inferenceFlexibleTToNullable.kt"); + } + @TestMetadata("unsafeNullCheck.kt") public void testUnsafeNullCheck() throws Exception { runTest("compiler/testData/codegen/box/platformTypes/unsafeNullCheck.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java index c6596c00216..d77ec0f1624 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java @@ -16595,6 +16595,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/platformTypes"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM_IR, true); } + @TestMetadata("inferenceFlexibleTToNullable.kt") + public void testInferenceFlexibleTToNullable() throws Exception { + runTest("compiler/testData/codegen/box/platformTypes/inferenceFlexibleTToNullable.kt"); + } + @TestMetadata("unsafeNullCheck.kt") public void testUnsafeNullCheck() throws Exception { runTest("compiler/testData/codegen/box/platformTypes/unsafeNullCheck.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index cc646d3867d..f528bf4c4e7 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -16595,6 +16595,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/platformTypes"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM_IR, true); } + @TestMetadata("inferenceFlexibleTToNullable.kt") + public void testInferenceFlexibleTToNullable() throws Exception { + runTest("compiler/testData/codegen/box/platformTypes/inferenceFlexibleTToNullable.kt"); + } + @TestMetadata("unsafeNullCheck.kt") public void testUnsafeNullCheck() throws Exception { runTest("compiler/testData/codegen/box/platformTypes/unsafeNullCheck.kt"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java index 0363bfa2cb1..9a233bd158e 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java @@ -13946,6 +13946,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/platformTypes"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS_IR, true); } + @TestMetadata("inferenceFlexibleTToNullable.kt") + public void testInferenceFlexibleTToNullable() throws Exception { + runTest("compiler/testData/codegen/box/platformTypes/inferenceFlexibleTToNullable.kt"); + } + @TestMetadata("compiler/testData/codegen/box/platformTypes/primitives") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index 6120f5044a7..002642a1d9a 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -15126,6 +15126,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/platformTypes"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS, true); } + @TestMetadata("inferenceFlexibleTToNullable.kt") + public void testInferenceFlexibleTToNullable() throws Exception { + runTest("compiler/testData/codegen/box/platformTypes/inferenceFlexibleTToNullable.kt"); + } + @TestMetadata("compiler/testData/codegen/box/platformTypes/primitives") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class)