diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java index a2e91491649..16b0b55f461 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java @@ -18164,6 +18164,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag runTest("compiler/testData/diagnostics/tests/j+k/flexibleNothing.kt"); } + @Test + @TestMetadata("flexibleTypeVariablePosition.kt") + public void testFlexibleTypeVariablePosition() throws Exception { + runTest("compiler/testData/diagnostics/tests/j+k/flexibleTypeVariablePosition.kt"); + } + @Test @TestMetadata("genericConstructorWithMultipleBounds.kt") public void testGenericConstructorWithMultipleBounds() throws Exception { @@ -19187,6 +19193,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag runTest("compiler/testData/diagnostics/tests/j+k/types/typeParameter.kt"); } + @Test + @TestMetadata("upperBoundsCheckAgainstSelfTypeInJava.kt") + public void testUpperBoundsCheckAgainstSelfTypeInJava() throws Exception { + runTest("compiler/testData/diagnostics/tests/j+k/types/upperBoundsCheckAgainstSelfTypeInJava.kt"); + } + @Test @TestMetadata("varargOverride.kt") public void testVarargOverride() throws Exception { @@ -23110,6 +23122,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag runTest("compiler/testData/diagnostics/tests/platformTypes/samConstructor.kt"); } + @Test + @TestMetadata("starProjectionToFlexibleVariable.kt") + public void testStarProjectionToFlexibleVariable() throws Exception { + runTest("compiler/testData/diagnostics/tests/platformTypes/starProjectionToFlexibleVariable.kt"); + } + @Test @TestMetadata("supertypeTypeArguments.kt") public void testSupertypeTypeArguments() throws Exception { @@ -37928,6 +37946,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithStdLib/java"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true); } + @Test + @TestMetadata("assertThatOnMap.kt") + public void testAssertThatOnMap() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/java/assertThatOnMap.kt"); + } + @Test @TestMetadata("checkEnhancedUpperBounds.kt") public void testCheckEnhancedUpperBounds() throws Exception { diff --git a/compiler/fir/analysis-tests/testData/resolve/arguments/lambdaInLambda2.fir.txt b/compiler/fir/analysis-tests/testData/resolve/arguments/lambdaInLambda2.fir.txt index bb9a26cbb16..c796ab139b0 100644 --- a/compiler/fir/analysis-tests/testData/resolve/arguments/lambdaInLambda2.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolve/arguments/lambdaInLambda2.fir.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, ft>| = R|/AdapterProcessor.AdapterProcessor||, R|ft|>(R|/Function||, R|ft|>( = Function@fun (method: R|PsiMethod?|): R|ft| { + lval processor: R|AdapterProcessor| = R|/AdapterProcessor.AdapterProcessor|(R|/Function||, R|ft|>( = Function@fun (method: R|PsiMethod?|): R|ft| { ^ R|/method|?.{ $subj$.R|/PsiMethod.containingClass| } } )) diff --git a/compiler/fir/analysis-tests/testData/resolve/arguments/typeMismatchOnExpectedJavaMap.fir.txt b/compiler/fir/analysis-tests/testData/resolve/arguments/typeMismatchOnExpectedJavaMap.fir.txt index c391b06e524..b2ca3021887 100644 --- a/compiler/fir/analysis-tests/testData/resolve/arguments/typeMismatchOnExpectedJavaMap.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolve/arguments/typeMismatchOnExpectedJavaMap.fir.txt @@ -1,4 +1,4 @@ FILE: main.kt public final fun test(executor: R|BuildActionExecuter|, modelType: R|java/lang/Class|, env: R|kotlin/collections/Map|): R|kotlin/Unit| { - lval model: R|ft>, BuildActionExecuter>?>| = R|/executor|.R|SubstitutionOverride>, BuildActionExecuter>?>|>|(R|/env|) + lval model: R|ft>, BuildActionExecuter>?>| = R|/executor|.R|SubstitutionOverride>, BuildActionExecuter>?>|>|(R|/env|) } diff --git a/compiler/fir/analysis-tests/testData/resolve/defaultJavaImportHiding.fir.txt b/compiler/fir/analysis-tests/testData/resolve/defaultJavaImportHiding.fir.txt index 55ceedf18cd..17376191360 100644 --- a/compiler/fir/analysis-tests/testData/resolve/defaultJavaImportHiding.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolve/defaultJavaImportHiding.fir.txt @@ -26,13 +26,13 @@ FILE: main.kt } public final fun test_1(): R|kotlin/Unit| { - lval map: R|util/HashMap, ft>| = R|util/HashMap.HashMap||, R|ft|>() + lval map: R|util/HashMap| = R|util/HashMap.HashMap|() } public final fun test_2(): R|kotlin/Unit| { lval set: R|util/HashSet| = R|util/HashSet.HashSet|() } public final fun test_3(): R|kotlin/Unit| { - lval list: R|foo/ArrayList>| = R|foo/ArrayList.ArrayList||>() + lval list: R|foo/ArrayList| = R|foo/ArrayList.ArrayList|() } public final fun test_4(): R|kotlin/Unit| { lval list: R|foo/LinkedList| = R|foo/LinkedList.LinkedList|() diff --git a/compiler/fir/analysis-tests/testData/resolve/expresssions/genericDiagnostic.fir.txt b/compiler/fir/analysis-tests/testData/resolve/expresssions/genericDiagnostic.fir.txt index c96ee4da060..239fbdd00a4 100644 --- a/compiler/fir/analysis-tests/testData/resolve/expresssions/genericDiagnostic.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolve/expresssions/genericDiagnostic.fir.txt @@ -13,8 +13,8 @@ FILE: test.kt lval element: R|DE| = R|/d|.R|/Diagnostic.element| R|/Fix.Fix|(R|/element|) } - private final val DERIVED_FACTORY: R|DiagnosticFactory0>| = R|/DiagnosticFactory0.DiagnosticFactory0||>() - private get(): R|DiagnosticFactory0>| + private final val DERIVED_FACTORY: R|DiagnosticFactory0| = R|/DiagnosticFactory0.DiagnosticFactory0|() + private get(): R|DiagnosticFactory0| public final fun createViaFactory(d: R|EmptyDiagnostic|): R|kotlin/Unit| { lval casted: R|Diagnostic>| = R|/DERIVED_FACTORY|.R|SubstitutionOverride>|>|(R|/d|) lval element: R|DerivedElement| = R|/casted|.R|/Diagnostic.element| diff --git a/compiler/fir/analysis-tests/testData/resolve/extendedCheckers/canBeReplacedWithOperatorAssignment/flexibleTypeBug.fir.txt b/compiler/fir/analysis-tests/testData/resolve/extendedCheckers/canBeReplacedWithOperatorAssignment/flexibleTypeBug.fir.txt index 11d5d96abda..f4b1bd6160a 100644 --- a/compiler/fir/analysis-tests/testData/resolve/extendedCheckers/canBeReplacedWithOperatorAssignment/flexibleTypeBug.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolve/extendedCheckers/canBeReplacedWithOperatorAssignment/flexibleTypeBug.fir.txt @@ -1,6 +1,6 @@ FILE: flexibleTypeBug.kt public final fun foo(): R|kotlin/Unit| { - lvar list1: R|ft>, kotlin/collections/List>?>| = Q|java/util/Collections|.R|java/util/Collections.emptyList||>() + lvar list1: R|ft>, kotlin/collections/List>?>| = Q|java/util/Collections|.R|java/util/Collections.emptyList|() lval list2: R|kotlin/collections/List| = R|kotlin/collections/listOf|(String(b)) R|/list1| = R|/list1|.R|kotlin/collections/plus||>(R|/list2|) } diff --git a/compiler/fir/analysis-tests/testData/resolve/problems/flexibleTypeVarAgainstNull.fir.txt b/compiler/fir/analysis-tests/testData/resolve/problems/flexibleTypeVarAgainstNull.fir.txt index 87ca7e2b9aa..921aec46e99 100644 --- a/compiler/fir/analysis-tests/testData/resolve/problems/flexibleTypeVarAgainstNull.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolve/problems/flexibleTypeVarAgainstNull.fir.txt @@ -1,4 +1,4 @@ FILE: main.kt public final fun main(): R|kotlin/Unit| { - R|/JavaClass.JavaClass||>(Null(null)).R|SubstitutionOverride|>|().R|kotlin/String.length| + R|/JavaClass.JavaClass|(Null(null)).R|SubstitutionOverride|>|().R|kotlin/String.length| } diff --git a/compiler/fir/analysis-tests/testData/resolve/samConstructors/genericSam.fir.txt b/compiler/fir/analysis-tests/testData/resolve/samConstructors/genericSam.fir.txt index 41a869921f1..14f4f447ac7 100644 --- a/compiler/fir/analysis-tests/testData/resolve/samConstructors/genericSam.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolve/samConstructors/genericSam.fir.txt @@ -1,6 +1,6 @@ FILE: main.kt public final fun main(): R|kotlin/Unit| { - R|/MyFunction||, R|ft|>( = MyFunction@fun (x: R|ft|): R|ft| { + R|/MyFunction|( = MyFunction@fun (x: R|ft|): R|ft| { ^ R|/x|.R|kotlin/Int.toInt|().R|kotlin/Int.toString|() } ) diff --git a/compiler/fir/analysis-tests/testData/resolve/scopes/publicJavaAndPrivateKotlinVar.overrides.txt b/compiler/fir/analysis-tests/testData/resolve/scopes/publicJavaAndPrivateKotlinVar.overrides.txt index 1e04e82ef69..2f26aa7aba5 100644 --- a/compiler/fir/analysis-tests/testData/resolve/scopes/publicJavaAndPrivateKotlinVar.overrides.txt +++ b/compiler/fir/analysis-tests/testData/resolve/scopes/publicJavaAndPrivateKotlinVar.overrides.txt @@ -2,8 +2,8 @@ C: [Source]: public open override fun getName(): R|kotlin/String| from Use site scope of /C [id: 0] [Enhancement]: public abstract fun getName(): R|ft| from Substitution scope for [Java enhancement scope for /B] for type C [id: 1] [Source]: public open override fun setName(newName: R|kotlin/String|): R|kotlin/Any?| from Use site scope of /C [id: 0] - [SubstitutionOverride]: public abstract fun setName(newName: R|ft|): R|kotlin/Any?| from Substitution scope for [Java enhancement scope for /B] for type C [id: 1] - [Enhancement]: public abstract fun setName(newName: R|ft|): R|ft| from Java enhancement scope for /B [id: 2] + [SubstitutionOverride]: public abstract fun setName(newName: R|ft|): R|ft| from Substitution scope for [Java enhancement scope for /B] for type C [id: 1] + [Enhancement]: public abstract fun setName(newName: R|ft|): R|ft| from Java enhancement scope for /B [id: 2] [Source]: private final var name: R|kotlin/String| = R|/name| from Use site scope of /C [id: 0] D: diff --git a/compiler/fir/analysis-tests/testData/resolve/smartcasts/kt50788.fir.txt b/compiler/fir/analysis-tests/testData/resolve/smartcasts/kt50788.fir.txt index 123697c878a..093b92f986c 100644 --- a/compiler/fir/analysis-tests/testData/resolve/smartcasts/kt50788.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolve/smartcasts/kt50788.fir.txt @@ -1,5 +1,5 @@ FILE: main.kt public final fun foo(mapper: R|Mapper|, cls: R|java/lang/Class?|): R|kotlin/Unit| { - lval result: R|T & Any| = R|/mapper|.R|/Mapper.readValue||>(R|/cls|)!! + lval result: R|T & Any| = R|/mapper|.R|/Mapper.readValue|(R|/cls|)!! R|/result|.R|kotlin/CharSequence.length| } diff --git a/compiler/fir/analysis-tests/testData/resolve/types/typeAliasInArguments.fir.txt b/compiler/fir/analysis-tests/testData/resolve/types/typeAliasInArguments.fir.txt index b28696611c1..6656ec01d69 100644 --- a/compiler/fir/analysis-tests/testData/resolve/types/typeAliasInArguments.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolve/types/typeAliasInArguments.fir.txt @@ -3,5 +3,5 @@ FILE: main.kt public final typealias ImmutableSet = R|MySet| private final typealias ImmutableMultimap = R|ImmutableMap>| private final fun R|ImmutableMultimap|.put(key: R|K|, value: R|V|, oldSet: R|ImmutableSet|): R|ImmutableMultimap| { - ^put this@R|/put|.R|SubstitutionOverride, ft, ImmutableSet?>>, MyMap, ft, ImmutableSet?>>?>|>|(R|/key|, R|/oldSet|.R|SubstitutionOverride>, MySet>?>|>|(R|/value|)) + ^put this@R|/put|.R|SubstitutionOverride, ft, ImmutableSet?>>, MyMap, ft, ImmutableSet?>>?>|>|(R|/key|, R|/oldSet|.R|SubstitutionOverride>, MySet>?>|>|(R|/value|)) } diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/concurrentMapOfAliases.fir.txt b/compiler/fir/analysis-tests/testData/resolveWithStdlib/concurrentMapOfAliases.fir.txt index a168fc30773..e3f134e7275 100644 --- a/compiler/fir/analysis-tests/testData/resolveWithStdlib/concurrentMapOfAliases.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/concurrentMapOfAliases.fir.txt @@ -5,8 +5,8 @@ FILE: concurrentMapOfAliases.kt super() } - private final val foo: R|java/util/concurrent/ConcurrentHashMap, ft>| = Q|java/util/concurrent|.R|java/util/concurrent/ConcurrentHashMap.ConcurrentHashMap||, R|ft|>() - private get(): R|java/util/concurrent/ConcurrentHashMap, ft>| + private final val foo: R|java/util/concurrent/ConcurrentHashMap| = Q|java/util/concurrent|.R|java/util/concurrent/ConcurrentHashMap.ConcurrentHashMap|() + private get(): R|java/util/concurrent/ConcurrentHashMap| private final fun bar(): R|kotlin/Unit| { this@R|/A|.R|/A.foo|.R|SubstitutionOverride|(String(dd))?.{ (this@R|/A|, $subj$).R|/A.baz|() } diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/j+k/flexibleTypeAliases.fir.txt b/compiler/fir/analysis-tests/testData/resolveWithStdlib/j+k/flexibleTypeAliases.fir.txt index 4f801c0eae0..ddcd781215a 100644 --- a/compiler/fir/analysis-tests/testData/resolveWithStdlib/j+k/flexibleTypeAliases.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/j+k/flexibleTypeAliases.fir.txt @@ -4,5 +4,5 @@ FILE: main.kt public final typealias ImmutableLinkedHashSet = R|imm/LinkedHashSet| private final typealias ImmutableMultimap = R|ImmutableMap>| private final fun R|ImmutableMultimap|.put(key: R|K|, value: R|V|): R|kotlin/Unit| { - this@R|/put|.R|SubstitutionOverride, ImmutableSet?>>, imm/Option, ImmutableSet?>>?>|>|(R|/key|).R|SubstitutionOverride, ImmutableSet?>|>|(Q|ImmutableLinkedHashSet|.R|imm/LinkedHashSet.empty||>()) + this@R|/put|.R|SubstitutionOverride, ImmutableSet?>>, imm/Option, ImmutableSet?>>?>|>|(R|/key|).R|SubstitutionOverride, ImmutableSet?>|>|(Q|ImmutableLinkedHashSet|.R|imm/LinkedHashSet.empty|()) } diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/javaLangComparator.fir.txt b/compiler/fir/analysis-tests/testData/resolveWithStdlib/javaLangComparator.fir.txt index 4231491c702..1352e3abbdb 100644 --- a/compiler/fir/analysis-tests/testData/resolveWithStdlib/javaLangComparator.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/javaLangComparator.fir.txt @@ -1,6 +1,6 @@ FILE: javaLangComparator.kt public final fun test_2(list: R|kotlin/collections/List|): R|kotlin/Unit| { - lval comp: R|java/util/Comparator>| = Q|java/util|.R|java/util/Comparator||>( = Comparator@fun (x: R|ft|, y: R|ft|): R|kotlin/Int| { + lval comp: R|java/util/Comparator| = Q|java/util|.R|java/util/Comparator|( = Comparator@fun (x: R|ft|, y: R|ft|): R|kotlin/Int| { ^ Int(1) } ) diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/kotlinComparatorAlias.fir.txt b/compiler/fir/analysis-tests/testData/resolveWithStdlib/kotlinComparatorAlias.fir.txt index a25562bf8c3..b7ca67fd07b 100644 --- a/compiler/fir/analysis-tests/testData/resolveWithStdlib/kotlinComparatorAlias.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/kotlinComparatorAlias.fir.txt @@ -1,6 +1,6 @@ FILE: kotlinComparatorAlias.kt public final fun test_1(): R|kotlin/Unit| { - lval comp: R|java/util/Comparator>| = R|java/util/Comparator||>( = Comparator@fun (x: R|ft|, y: R|ft|): R|kotlin/Int| { + lval comp: R|java/util/Comparator| = R|java/util/Comparator|( = Comparator@fun (x: R|ft|, y: R|ft|): R|kotlin/Int| { ^ Int(1) } ) diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/problems/weakHashMap.fir.txt b/compiler/fir/analysis-tests/testData/resolveWithStdlib/problems/weakHashMap.fir.txt index a7102190e78..95ddeae9275 100644 --- a/compiler/fir/analysis-tests/testData/resolveWithStdlib/problems/weakHashMap.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/problems/weakHashMap.fir.txt @@ -1,6 +1,6 @@ FILE: weakHashMap.kt - public final val someMap: R|java/util/WeakHashMap, ft>| = R|java/util/WeakHashMap.WeakHashMap||, R|ft|>() - public get(): R|java/util/WeakHashMap, ft>| + public final val someMap: R|java/util/WeakHashMap| = R|java/util/WeakHashMap.WeakHashMap|() + public get(): R|java/util/WeakHashMap| public final fun foo(): R|kotlin/Unit| { R|/someMap|.R|SubstitutionOverride|(String()) } diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/typeAliasWithForEach.fir.txt b/compiler/fir/analysis-tests/testData/resolveWithStdlib/typeAliasWithForEach.fir.txt index 8715a49a95f..73a9970cfda 100644 --- a/compiler/fir/analysis-tests/testData/resolveWithStdlib/typeAliasWithForEach.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/typeAliasWithForEach.fir.txt @@ -9,9 +9,9 @@ FILE: typeAliasWithForEach.kt } public final typealias Arguments = R|kotlin/collections/Map| public final fun R|Arguments|.deepCopy(): R|Arguments| { - lval result: R|java/util/HashMap, ft>| = R|java/util/HashMap.HashMap||, R|ft|>() + lval result: R|java/util/HashMap| = R|java/util/HashMap.HashMap|() this@R|/deepCopy|.R|SubstitutionOverride|( = forEach@fun (key: R|@EnhancedNullability kotlin/String|, value: R|@EnhancedNullability ArgsInfo|): R|kotlin/Unit| { - R|/result|.R|kotlin/collections/set||, R|ft|>(R|/key|, R|/ArgsInfoImpl.ArgsInfoImpl|(R|/value|)) + R|/result|.R|kotlin/collections/set|(R|/key|, R|/ArgsInfoImpl.ArgsInfoImpl|(R|/value|)) } ) ^deepCopy R|/result| diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java index 0dd480dab2b..9ea853848d0 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java @@ -18164,6 +18164,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti runTest("compiler/testData/diagnostics/tests/j+k/flexibleNothing.kt"); } + @Test + @TestMetadata("flexibleTypeVariablePosition.kt") + public void testFlexibleTypeVariablePosition() throws Exception { + runTest("compiler/testData/diagnostics/tests/j+k/flexibleTypeVariablePosition.kt"); + } + @Test @TestMetadata("genericConstructorWithMultipleBounds.kt") public void testGenericConstructorWithMultipleBounds() throws Exception { @@ -19187,6 +19193,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti runTest("compiler/testData/diagnostics/tests/j+k/types/typeParameter.kt"); } + @Test + @TestMetadata("upperBoundsCheckAgainstSelfTypeInJava.kt") + public void testUpperBoundsCheckAgainstSelfTypeInJava() throws Exception { + runTest("compiler/testData/diagnostics/tests/j+k/types/upperBoundsCheckAgainstSelfTypeInJava.kt"); + } + @Test @TestMetadata("varargOverride.kt") public void testVarargOverride() throws Exception { @@ -23110,6 +23122,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti runTest("compiler/testData/diagnostics/tests/platformTypes/samConstructor.kt"); } + @Test + @TestMetadata("starProjectionToFlexibleVariable.kt") + public void testStarProjectionToFlexibleVariable() throws Exception { + runTest("compiler/testData/diagnostics/tests/platformTypes/starProjectionToFlexibleVariable.kt"); + } + @Test @TestMetadata("supertypeTypeArguments.kt") public void testSupertypeTypeArguments() throws Exception { @@ -37928,6 +37946,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithStdLib/java"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true); } + @Test + @TestMetadata("assertThatOnMap.kt") + public void testAssertThatOnMap() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/java/assertThatOnMap.kt"); + } + @Test @TestMetadata("checkEnhancedUpperBounds.kt") public void testCheckEnhancedUpperBounds() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java index 68680b7ed58..d6f4af93ff7 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java @@ -18164,6 +18164,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac runTest("compiler/testData/diagnostics/tests/j+k/flexibleNothing.kt"); } + @Test + @TestMetadata("flexibleTypeVariablePosition.kt") + public void testFlexibleTypeVariablePosition() throws Exception { + runTest("compiler/testData/diagnostics/tests/j+k/flexibleTypeVariablePosition.kt"); + } + @Test @TestMetadata("genericConstructorWithMultipleBounds.kt") public void testGenericConstructorWithMultipleBounds() throws Exception { @@ -19187,6 +19193,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac runTest("compiler/testData/diagnostics/tests/j+k/types/typeParameter.kt"); } + @Test + @TestMetadata("upperBoundsCheckAgainstSelfTypeInJava.kt") + public void testUpperBoundsCheckAgainstSelfTypeInJava() throws Exception { + runTest("compiler/testData/diagnostics/tests/j+k/types/upperBoundsCheckAgainstSelfTypeInJava.kt"); + } + @Test @TestMetadata("varargOverride.kt") public void testVarargOverride() throws Exception { @@ -23110,6 +23122,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac runTest("compiler/testData/diagnostics/tests/platformTypes/samConstructor.kt"); } + @Test + @TestMetadata("starProjectionToFlexibleVariable.kt") + public void testStarProjectionToFlexibleVariable() throws Exception { + runTest("compiler/testData/diagnostics/tests/platformTypes/starProjectionToFlexibleVariable.kt"); + } + @Test @TestMetadata("supertypeTypeArguments.kt") public void testSupertypeTypeArguments() throws Exception { @@ -37928,6 +37946,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithStdLib/java"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true); } + @Test + @TestMetadata("assertThatOnMap.kt") + public void testAssertThatOnMap() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/java/assertThatOnMap.kt"); + } + @Test @TestMetadata("checkEnhancedUpperBounds.kt") public void testCheckEnhancedUpperBounds() throws Exception { diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaTypeConversion.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaTypeConversion.kt index d32f5990ce3..a3ea4a58bc3 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaTypeConversion.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaTypeConversion.kt @@ -102,7 +102,19 @@ private fun JavaType?.toConeTypeProjection( return lowerBound } val upperBound = toConeKotlinTypeForFlexibleBound(session, javaTypeParameterStack, mode, attributes, lowerBound) - if (isRaw) ConeRawType(lowerBound, upperBound) else ConeFlexibleType(lowerBound, upperBound) + + val finalLowerBound = when (lowerBound) { + is ConeTypeParameterType -> + ConeDefinitelyNotNullType.create( + lowerBound, session.typeContext, + // Upper bounds might be not initialized properly yet, so we force creating DefinitelyNotNullType + // It should not affect semantics, since it would be still a valid type anyway + forceWithoutCheck = true, + ) ?: lowerBound + else -> lowerBound + } + + if (isRaw) ConeRawType(finalLowerBound, upperBound) else ConeFlexibleType(finalLowerBound, upperBound) } is JavaArrayType -> { diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/javaTypeUtils.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/javaTypeUtils.kt index 03d41c90840..4bf431ba01e 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/javaTypeUtils.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/javaTypeUtils.kt @@ -92,7 +92,12 @@ private fun ConeSimpleKotlinType.enhanceInflexibleType( qualifiers: IndexedJavaTypeQualifiers, index: Int, subtreeSizes: List, + isFromDefinitelyNotNullType: Boolean = false, ): ConeSimpleKotlinType? { + if (this is ConeDefinitelyNotNullType) { + return original.enhanceInflexibleType(session, position, qualifiers, index, subtreeSizes, isFromDefinitelyNotNullType = true) + } + val shouldEnhance = position.shouldEnhance() if ((!shouldEnhance && typeArguments.isEmpty()) || this !is ConeLookupTagBasedType) { return null @@ -104,7 +109,7 @@ private fun ConeSimpleKotlinType.enhanceInflexibleType( // TODO: implement warnings val nullabilityFromQualifiers = effectiveQualifiers.nullability .takeIf { shouldEnhance && !effectiveQualifiers.isNullabilityQualifierForWarning } - val enhancedNullability = when (nullabilityFromQualifiers) { + val enhancedIsNullable = when (nullabilityFromQualifiers) { NullabilityQualifier.NULLABLE -> true NullabilityQualifier.NOT_NULL -> false else -> isNullable @@ -124,14 +129,14 @@ private fun ConeSimpleKotlinType.enhanceInflexibleType( } val shouldAddAttribute = nullabilityFromQualifiers == NullabilityQualifier.NOT_NULL && !hasEnhancedNullability - if (lookupTag == enhancedTag && enhancedNullability == isNullable && !shouldAddAttribute && enhancedArguments.all { it == null }) { + if (lookupTag == enhancedTag && enhancedIsNullable == isNullable && !shouldAddAttribute && enhancedArguments.all { it == null }) { return null // absolutely no changes } val mergedArguments = Array(typeArguments.size) { enhancedArguments[it] ?: typeArguments[it] } val mergedAttributes = if (shouldAddAttribute) attributes + CompilerConeAttributes.EnhancedNullability else attributes - val enhancedType = enhancedTag.constructType(mergedArguments, enhancedNullability, mergedAttributes) - return if (effectiveQualifiers.definitelyNotNull) + val enhancedType = enhancedTag.constructType(mergedArguments, enhancedIsNullable, mergedAttributes) + return if (effectiveQualifiers.definitelyNotNull || (isFromDefinitelyNotNullType && nullabilityFromQualifiers == null)) ConeDefinitelyNotNullType.create(enhancedType, session.typeContext) ?: enhancedType else enhancedType diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/resolve/substitution/Substitutors.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/resolve/substitution/Substitutors.kt index 76657f3e59e..1a720384a2c 100644 --- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/resolve/substitution/Substitutors.kt +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/resolve/substitution/Substitutors.kt @@ -103,10 +103,12 @@ abstract class AbstractConeSubstitutor(protected val typeContext: ConeTypeContex } private fun ConeDefinitelyNotNullType.substituteOriginal(): ConeKotlinType? { - val substituted = substituteOrNull(original) - ?.withNullability(ConeNullability.NOT_NULL, typeContext) - ?.withAttributes(original.attributes) - ?: return null + val substitutedOriginal = substituteOrNull(original) ?: return null + val substituted = substitutedOriginal.withNullability( + ConeNullability.NOT_NULL, + typeContext, + substitutedOriginal.attributes.add(original.attributes) + ) return ConeDefinitelyNotNullType.create(substituted, typeContext) ?: substituted } diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ConeInferenceContext.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ConeInferenceContext.kt index ec5228e8a11..762efcfc83c 100644 --- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ConeInferenceContext.kt +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ConeInferenceContext.kt @@ -562,8 +562,7 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo return intersectionType.withAlternative(secondCandidate) } - override fun SimpleTypeMarker.createConstraintPartForLowerBoundAndFlexibleTypeVariable(): KotlinTypeMarker = - createFlexibleType(this.makeSimpleTypeDefinitelyNotNullOrNotNull(), this.withNullability(true)) + override fun useRefinedBoundsForTypeVariableInFlexiblePosition(): Boolean = true override fun createSubstitutorForSuperTypes(baseType: KotlinTypeMarker): TypeSubstitutorMarker? = if (baseType is ConeLookupTagBasedType) createSubstitutionForSupertype(baseType, session) else null diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt index 8d918054588..16d1ba9c215 100644 --- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt @@ -13,7 +13,10 @@ import org.jetbrains.kotlin.descriptors.ValueClassKind import org.jetbrains.kotlin.descriptors.valueClassLoweringKind import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.* -import org.jetbrains.kotlin.fir.declarations.utils.* +import org.jetbrains.kotlin.fir.declarations.utils.expandedConeType +import org.jetbrains.kotlin.fir.declarations.utils.isInner +import org.jetbrains.kotlin.fir.declarations.utils.modality +import org.jetbrains.kotlin.fir.declarations.utils.superConeTypes import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.resolve.directExpansionType import org.jetbrains.kotlin.fir.resolve.fullyExpandedType @@ -289,7 +292,7 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty else -> listOf(session.builtinTypes.anyType.type) } } - is ConeCapturedTypeConstructor -> supertypes!! + is ConeCapturedTypeConstructor -> supertypes.orEmpty() is ConeIntersectionType -> intersectedTypes is ConeIntegerLiteralType -> supertypes else -> unknownConstructorError() @@ -475,13 +478,13 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty return when (this) { is ConeFlexibleType -> this.upperBound.isNullableType() - is ConeTypeParameterType -> lookupTag.symbol.allBoundsAreNullable() + is ConeTypeParameterType -> lookupTag.symbol.allBoundsAreNullableOrUnresolved() is ConeTypeVariableType -> { val symbol = lookupTag.toSymbol(session) ?: return false when (symbol) { is FirClassSymbol -> false is FirTypeAliasSymbol -> symbol.fir.expandedConeType?.isNullableType() ?: false - is FirTypeParameterSymbol -> symbol.allBoundsAreNullable() + is FirTypeParameterSymbol -> symbol.allBoundsAreNullableOrUnresolved() } } is ConeIntersectionType -> intersectedTypes.all { it.isNullableType() } @@ -490,8 +493,13 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty } } - private fun FirTypeParameterSymbol.allBoundsAreNullable(): Boolean { - return resolvedBounds.all { it.coneType.isNullableType() } + private fun FirTypeParameterSymbol.allBoundsAreNullableOrUnresolved(): Boolean { + for (bound in fir.bounds) { + if (bound !is FirResolvedTypeRef) return true + if (!bound.type.isNullableType()) return false + } + + return true } private fun TypeConstructorMarker.toFirRegularClass(): FirRegularClass? { diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/TypeUtils.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/TypeUtils.kt index 5085dfab1c1..665f824f592 100644 --- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/TypeUtils.kt +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/TypeUtils.kt @@ -60,7 +60,7 @@ fun TypeCheckerProviderContext.equalTypes(a: ConeKotlinType, b: ConeKotlinType): private fun ConeTypeContext.makesSenseToBeDefinitelyNotNull(originalType: ConeKotlinType): Boolean { return when (val type = originalType.lowerBoundIfFlexible()) { - is ConeTypeParameterType -> type.isNullableType() + is ConeTypeParameterType -> !type.lookupTag.symbol.isInitializedFir || type.isNullableType() // Actually, this branch should work for type parameters as well, but it breaks some cases. See KT-40114. // Basically, if we have `T : X..X?`, then `T <: Any` but we still have `T` != `T & Any`. is ConeTypeVariableType, is ConeCapturedType -> { @@ -75,12 +75,13 @@ private fun ConeTypeContext.makesSenseToBeDefinitelyNotNull(originalType: ConeKo fun ConeDefinitelyNotNullType.Companion.create( original: ConeKotlinType, - typeContext: ConeTypeContext + typeContext: ConeTypeContext, + forceWithoutCheck: Boolean = false, ): ConeDefinitelyNotNullType? { return when (original) { is ConeDefinitelyNotNullType -> original is ConeFlexibleType -> create(original.lowerBound, typeContext) - is ConeSimpleKotlinType -> runIf(typeContext.makesSenseToBeDefinitelyNotNull(original)) { + is ConeSimpleKotlinType -> runIf(forceWithoutCheck || typeContext.makesSenseToBeDefinitelyNotNull(original)) { ConeDefinitelyNotNullType(original.coneLowerBoundIfFlexible()) } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CreateFreshTypeVariableSubstitutorStage.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CreateFreshTypeVariableSubstitutorStage.kt index 3c444e7336f..e3686870d6a 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CreateFreshTypeVariableSubstitutorStage.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CreateFreshTypeVariableSubstitutorStage.kt @@ -15,7 +15,6 @@ import org.jetbrains.kotlin.fir.resolve.inference.model.ConeExplicitTypeParamete import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap import org.jetbrains.kotlin.fir.scopes.impl.toConeType -import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag import org.jetbrains.kotlin.fir.symbols.ensureResolved import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.name.StandardClassIds @@ -66,11 +65,7 @@ internal object CreateFreshTypeVariableSubstitutorStage : ResolutionStage() { when (val typeArgument = candidate.typeArgumentMapping[index]) { is FirTypeProjectionWithVariance -> csBuilder.addEqualityConstraint( freshVariable.defaultType, - getTypePreservingFlexibilityWrtTypeVariable( - typeArgument.typeRef.coneType, - typeParameter, - context.session - ).fullyExpandedType(context.session), + typeArgument.typeRef.coneType.fullyExpandedType(context.session), ConeExplicitTypeParameterConstraintPosition(typeArgument) ) is FirStarProjection -> csBuilder.addEqualityConstraint( @@ -85,29 +80,6 @@ internal object CreateFreshTypeVariableSubstitutorStage : ResolutionStage() { } } } - - private fun getTypePreservingFlexibilityWrtTypeVariable( - type: ConeKotlinType, - typeParameter: FirTypeParameterRef, - session: FirSession, - ): ConeKotlinType { - return if (typeParameter.shouldBeFlexible(session.typeContext)) { - val notNullType = type.withNullability(ConeNullability.NOT_NULL, session.typeContext) as ConeSimpleKotlinType - ConeFlexibleType(notNullType, notNullType.withNullability(ConeNullability.NULLABLE, session.typeContext)) - } else { - type - } - } - - private fun FirTypeParameterRef.shouldBeFlexible(context: ConeTypeContext): Boolean { - return symbol.resolvedBounds.any { - val type = it.coneType - type is ConeFlexibleType || with(context) { - (type.typeConstructor() as? ConeTypeParameterLookupTag)?.symbol?.fir?.shouldBeFlexible(context) ?: false - } - } - } - } private fun createToFreshVariableSubstitutorAndAddInitialConstraints( diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/ConeConstraintSystemUtilContext.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/ConeConstraintSystemUtilContext.kt index f2313e9bb0a..0421e0ca70c 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/ConeConstraintSystemUtilContext.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/ConeConstraintSystemUtilContext.kt @@ -21,7 +21,8 @@ import org.jetbrains.kotlin.types.model.TypeVariableMarker object ConeConstraintSystemUtilContext : ConstraintSystemUtilContext { override fun TypeVariableMarker.shouldBeFlexible(): Boolean { - // TODO + // In FIR, there's no need in hack with shouldTryUseDifferentFlexibilityForUpperType + // See org.jetbrains.kotlin.types.model.TypeSystemInferenceExtensionContext.useRefinedBoundsForTypeVariableInFlexiblePosition return false } diff --git a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/ConstraintIncorporator.kt b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/ConstraintIncorporator.kt index 070cc9ff100..50beb0578c3 100644 --- a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/ConstraintIncorporator.kt +++ b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/ConstraintIncorporator.kt @@ -59,7 +59,11 @@ class ConstraintIncorporator( typeVariable: TypeVariableMarker, constraint: Constraint ) { - val shouldBeTypeVariableFlexible = with(utilContext) { typeVariable.shouldBeFlexible() } + val shouldBeTypeVariableFlexible = + if (useRefinedBoundsForTypeVariableInFlexiblePosition()) + false + else + with(utilContext) { typeVariable.shouldBeFlexible() } // \alpha <: constraint.type if (constraint.kind != ConstraintKind.LOWER) { diff --git a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/TypeCheckerStateForConstraintSystem.kt b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/TypeCheckerStateForConstraintSystem.kt index 0b8f0275ec5..a21ea36594d 100644 --- a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/TypeCheckerStateForConstraintSystem.kt +++ b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/TypeCheckerStateForConstraintSystem.kt @@ -174,9 +174,9 @@ abstract class TypeCheckerStateForConstraintSystem( * * T? * - * Foo <: T? -- Foo & Any <: T -- Foo!! <: T - * Foo? <: T? -- Foo? & Any <: T -- Foo!! <: T - * (Foo..Bar) <: T? -- (Foo..Bar) & Any <: T -- (Foo..Bar)!! <: T + * Foo <: T? -- Foo & Any <: T + * Foo? <: T? -- Foo? & Any <: T -- Foo & Any <: T + * (Foo..Bar) <: T? -- (Foo..Bar) & Any <: T * * T! * @@ -248,12 +248,34 @@ abstract class TypeCheckerStateForConstraintSystem( when (subType) { is SimpleTypeMarker -> - // Foo <: T! -- (Foo!! .. Foo) <: T - subType.createConstraintPartForLowerBoundAndFlexibleTypeVariable() + when { + useRefinedBoundsForTypeVariableInFlexiblePosition() -> + // Foo <: T! -- (Foo!! .. Foo) <: T + createFlexibleType( + subType.makeSimpleTypeDefinitelyNotNullOrNotNull(), + subType.withNullability(true) + ) + // In K1 (FE1.0), there is an obsolete behavior + subType.isMarkedNullable() -> subType + else -> createFlexibleType(subType, subType.withNullability(true)) + } is FlexibleTypeMarker -> - // (Foo..Bar) <: T! -- (Foo!! .. Bar) <: T - createFlexibleType(subType.lowerBound().makeSimpleTypeDefinitelyNotNullOrNotNull(), subType.upperBound()) + + when { + useRefinedBoundsForTypeVariableInFlexiblePosition() -> + // (Foo..Bar) <: T! -- (Foo!! .. Bar?) <: T + createFlexibleType( + subType.lowerBound().makeSimpleTypeDefinitelyNotNullOrNotNull(), + subType.upperBound().withNullability(true) + ) + else -> + // (Foo..Bar) <: T! -- (Foo!! .. Bar) <: T + createFlexibleType( + subType.lowerBound().makeSimpleTypeDefinitelyNotNullOrNotNull(), + subType.upperBound() + ) + } else -> error("sealed") } @@ -273,17 +295,29 @@ abstract class TypeCheckerStateForConstraintSystem( } /** - * T! <: Foo <=> T <: Foo..Foo? + * T! <: Foo <=> T <: Foo & Any..Foo? * T? <: Foo <=> T <: Foo && Nothing? <: Foo * T <: Foo -- leave as is */ private fun simplifyUpperConstraint(typeVariable: KotlinTypeMarker, superType: KotlinTypeMarker): Boolean = with(extensionTypeContext) { val typeVariableLowerBound = typeVariable.lowerBoundIfFlexible() - val simplifiedSuperType = if (typeVariableLowerBound.isDefinitelyNotNullType()) { - superType.withNullability(true) - } else if (typeVariable.isFlexible() && superType is SimpleTypeMarker) { - createFlexibleType(superType, superType.withNullability(true)) - } else superType + + val simplifiedSuperType = when { + typeVariable.isFlexible() && useRefinedBoundsForTypeVariableInFlexiblePosition() -> + createFlexibleType( + superType.lowerBoundIfFlexible().makeSimpleTypeDefinitelyNotNullOrNotNull(), + superType.upperBoundIfFlexible().withNullability(true) + ) + + typeVariableLowerBound.isDefinitelyNotNullType() -> { + superType.withNullability(true) + } + + typeVariable.isFlexible() && superType is SimpleTypeMarker -> + createFlexibleType(superType, superType.withNullability(true)) + + else -> superType + } addUpperConstraint(typeVariableLowerBound.typeConstructor(), simplifiedSuperType) diff --git a/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/strictMode/Captured.fir.kt b/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/strictMode/Captured.fir.kt deleted file mode 100644 index aa6e98bed6c..00000000000 --- a/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/strictMode/Captured.fir.kt +++ /dev/null @@ -1,17 +0,0 @@ -// JSPECIFY_STATE: strict -// !LANGUAGE: +TypeEnhancementImprovementsInStrictMode -// FILE: J1.java -import org.jetbrains.annotations.Nullable; - -public interface J1 { - @Nullable - public static T foo(J1 x) { return null; } -} - -// FILE: J2.java -import org.jspecify.nullness.Nullable; - -public interface J2 extends J1 { } - -// FILE: kotlin.kt -private fun J2<*>.bar() = J1.foo(this) diff --git a/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/strictMode/Captured.kt b/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/strictMode/Captured.kt index cc6a973addf..f0aa0bebf42 100644 --- a/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/strictMode/Captured.kt +++ b/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/strictMode/Captured.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // JSPECIFY_STATE: strict // !LANGUAGE: +TypeEnhancementImprovementsInStrictMode // FILE: J1.java diff --git a/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/misc/returnType.fir.kt b/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/misc/returnType.fir.kt index 5ffa631c516..9e7afe98bd6 100644 --- a/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/misc/returnType.fir.kt +++ b/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/misc/returnType.fir.kt @@ -37,7 +37,7 @@ fun main(a: ReturnType) { takeNullableStringAndKNullable(x1) takeNotNullStringAndNotNullK(x1) takeNullableStringAndNotNullK(x1) - takeNotNullString(a.foo41.foo411) + takeNotNullString(a.foo41.foo411) val x2 = ..ReturnType.A?!")!>a.foo2() takeNotNullStringAndKNullable(x2) diff --git a/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/misc/returnTypeWithWarnings.fir.kt b/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/misc/returnTypeWithWarnings.fir.kt index d82b4e8a073..a4f90d4e4c9 100644 --- a/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/misc/returnTypeWithWarnings.fir.kt +++ b/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/misc/returnTypeWithWarnings.fir.kt @@ -39,7 +39,7 @@ fun main(a: ReturnTypeWithWarnings) { takeNullableStringAndKNullable(x1) takeNotNullStringAndNotNullK(x1) takeNullableStringAndNotNullK(x1) - takeNotNullString(a.foo41.foo411) + takeNotNullString(a.foo41.foo411) val x2 = ..ReturnTypeWithWarnings.A?!")!>a.foo2() takeNotNullStringAndKNullable(x2) diff --git a/compiler/testData/diagnostics/tests/explicitDefinitelyNotNullableViaIntersection/overridesJavaAnnotated.fir.kt b/compiler/testData/diagnostics/tests/explicitDefinitelyNotNullableViaIntersection/overridesJavaAnnotated.fir.kt new file mode 100644 index 00000000000..1d9271fe438 --- /dev/null +++ b/compiler/testData/diagnostics/tests/explicitDefinitelyNotNullableViaIntersection/overridesJavaAnnotated.fir.kt @@ -0,0 +1,42 @@ +// !LANGUAGE: +DefinitelyNonNullableTypes +ProhibitUsingNullableTypeParameterAgainstNotNullAnnotated + +// FILE: A.java +import org.jetbrains.annotations.*; + +public interface A { + public T foo(T x) { return x; } + @NotNull + public T bar(@NotNull T x) {} +} + +// FILE: main.kt + +interface B : A { + override fun foo(x: T1): T1 + override fun bar(x: T1 & Any): T1 & Any +} + +interface C : A { + override fun foo(x: T2 & Any): T2 & Any + override fun bar(x: T2): T2 +} + +interface D : A { + override fun foo(x: String?): String? + override fun bar(x: String): String +} + +interface E : A { + override fun foo(x: String): String + override fun bar(x: String): String +} + +interface F : A { + override fun foo(x: String): String + override fun bar(x: String?): String? +} + +interface G : A { + override fun foo(x: T3): T3 + override fun bar(x: T3): T3 +} diff --git a/compiler/testData/diagnostics/tests/explicitDefinitelyNotNullableViaIntersection/overridesJavaAnnotated.kt b/compiler/testData/diagnostics/tests/explicitDefinitelyNotNullableViaIntersection/overridesJavaAnnotated.kt index 8fc72d541dc..4d0839a47ef 100644 --- a/compiler/testData/diagnostics/tests/explicitDefinitelyNotNullableViaIntersection/overridesJavaAnnotated.kt +++ b/compiler/testData/diagnostics/tests/explicitDefinitelyNotNullableViaIntersection/overridesJavaAnnotated.kt @@ -1,4 +1,3 @@ -// FIR_IDENTICAL // !LANGUAGE: +DefinitelyNonNullableTypes +ProhibitUsingNullableTypeParameterAgainstNotNullAnnotated // FILE: A.java diff --git a/compiler/testData/diagnostics/tests/inference/findViewById.fir.kt b/compiler/testData/diagnostics/tests/inference/findViewById.fir.kt index 79e20e83328..9921888d514 100644 --- a/compiler/testData/diagnostics/tests/inference/findViewById.fir.kt +++ b/compiler/testData/diagnostics/tests/inference/findViewById.fir.kt @@ -27,7 +27,7 @@ val xExplicit: X = Test().findViewById(0) val xCast = Test().findViewById(0) as X val xCastExplicitType = Test().findViewById(0) as X -val xSafeCastExplicitType = Test().findViewById(0) as? X +val xSafeCastExplicitType = Test().findViewById(0) as? X val yExplicit: Y = Test().findViewById(0) val yCast = Test().findViewById(0) as Y diff --git a/compiler/testData/diagnostics/tests/j+k/flexibleTypeVariablePosition.fir.kt b/compiler/testData/diagnostics/tests/j+k/flexibleTypeVariablePosition.fir.kt new file mode 100644 index 00000000000..97ac9770856 --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/flexibleTypeVariablePosition.fir.kt @@ -0,0 +1,20 @@ +// SKIP_TXT +// FILE: JavaClass.java +public class JavaClass { + public static K simpleId(K k) { // fun simpleId(k: K & Any..K?): K & Any..K? = + return k; + } +} + +// FILE: main.kt + +fun takeN(n: Number?): Int = 1 + +fun bar(n: Number?) { + fun takeN(n: Number): String = "" + + // in K1, it was resolved to nullable takeN + // in K2, it would be resolved to not-nullable and may fail with NPE + takeN(JavaClass.simpleId(n)).div(1) + takeN(JavaClass.simpleId(n)).length +} diff --git a/compiler/testData/diagnostics/tests/j+k/flexibleTypeVariablePosition.kt b/compiler/testData/diagnostics/tests/j+k/flexibleTypeVariablePosition.kt new file mode 100644 index 00000000000..5f27344cda4 --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/flexibleTypeVariablePosition.kt @@ -0,0 +1,20 @@ +// SKIP_TXT +// FILE: JavaClass.java +public class JavaClass { + public static K simpleId(K k) { // fun simpleId(k: K & Any..K?): K & Any..K? = + return k; + } +} + +// FILE: main.kt + +fun takeN(n: Number?): Int = 1 + +fun bar(n: Number?) { + fun takeN(n: Number): String = "" + + // in K1, it was resolved to nullable takeN + // in K2, it would be resolved to not-nullable and may fail with NPE + takeN(JavaClass.simpleId(n)).div(1) + takeN(JavaClass.simpleId(n)).length +} diff --git a/compiler/testData/diagnostics/tests/j+k/types/upperBoundsCheckAgainstSelfTypeInJava.kt b/compiler/testData/diagnostics/tests/j+k/types/upperBoundsCheckAgainstSelfTypeInJava.kt new file mode 100644 index 00000000000..d4ae952fb8f --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/types/upperBoundsCheckAgainstSelfTypeInJava.kt @@ -0,0 +1,11 @@ +// FIR_IDENTICAL +// SKIP_TXT +// FILE: XBreakpointProperties.java +public abstract class XBreakpointProperties {} +// FILE: XBreakpoint.java +public interface XBreakpoint

{} +// FILE: XBreakpointType.java +public abstract class XBreakpointType, P extends XBreakpointProperties> {} + +// FILE: main.kt +fun foo(x: XBreakpointType, *>) {} diff --git a/compiler/testData/diagnostics/tests/platformTypes/notNullTypeParameter/methodTypeParameter.fir.kt b/compiler/testData/diagnostics/tests/platformTypes/notNullTypeParameter/methodTypeParameter.fir.kt index 2951967aafc..8fd4acd73b7 100644 --- a/compiler/testData/diagnostics/tests/platformTypes/notNullTypeParameter/methodTypeParameter.fir.kt +++ b/compiler/testData/diagnostics/tests/platformTypes/notNullTypeParameter/methodTypeParameter.fir.kt @@ -12,7 +12,7 @@ public class A { fun test() { A.bar(null, "") - A.bar(null, "") + A.bar(null, "") A.bar(null, "") A.bar(null, A.platformString()) } diff --git a/compiler/testData/diagnostics/tests/platformTypes/nullableTypeArgument.fir.kt b/compiler/testData/diagnostics/tests/platformTypes/nullableTypeArgument.fir.kt deleted file mode 100644 index 56780f13fc7..00000000000 --- a/compiler/testData/diagnostics/tests/platformTypes/nullableTypeArgument.fir.kt +++ /dev/null @@ -1,9 +0,0 @@ -import java.util.ArrayList - -fun foo() { - val list = ArrayList() - - for (s in list) { - s.length - } -} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/platformTypes/nullableTypeArgument.kt b/compiler/testData/diagnostics/tests/platformTypes/nullableTypeArgument.kt index 268c905ad05..004578ace4a 100644 --- a/compiler/testData/diagnostics/tests/platformTypes/nullableTypeArgument.kt +++ b/compiler/testData/diagnostics/tests/platformTypes/nullableTypeArgument.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL import java.util.ArrayList fun foo() { diff --git a/compiler/testData/diagnostics/tests/platformTypes/starProjectionToFlexibleVariable.kt b/compiler/testData/diagnostics/tests/platformTypes/starProjectionToFlexibleVariable.kt new file mode 100644 index 00000000000..b345f8794b3 --- /dev/null +++ b/compiler/testData/diagnostics/tests/platformTypes/starProjectionToFlexibleVariable.kt @@ -0,0 +1,20 @@ +// FIR_IDENTICAL +// SKIP_TXT +// FILE: ExtensionPointName.java +public final class ExtensionPointName {} +// FILE: ExtensionPoint.java +import org.jetbrains.annotations.NotNull; + +public interface ExtensionPoint<@NotNull T> { + T foo(); +} +// FILE: Area.java +public class Area { + @NotNull + public static ExtensionPoint getExtensionPoint(@NotNull ExtensionPointName extensionPointName) { return null; } +} +// FILE: main.kt + +private fun unregisterEverything(extensionPoint: ExtensionPointName<*>) { + Area.getExtensionPoint(extensionPoint).foo().hashCode() +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/inference/recursiveFlexibleAssertions.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/inference/recursiveFlexibleAssertions.fir.kt index de73553daf9..a72991408a1 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/inference/recursiveFlexibleAssertions.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/inference/recursiveFlexibleAssertions.fir.kt @@ -75,5 +75,5 @@ fun test() { } // TODO: FIR // {AbstractAssert<*, out Any!>! & EnumerableAssert<*, {Comparable<*> & java.io.Serializable!}>!} with unfolded flexible nullability - & EnumerableAssert<*, out kotlin.Comparable & java.io.Serializable..kotlin.Comparable? & java.io.Serializable?>..AbstractAssert<*, out kotlin.Any..kotlin.Any?!>? & EnumerableAssert<*, out kotlin.Comparable & java.io.Serializable..kotlin.Comparable? & java.io.Serializable?>?")!>assertion + & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Any..kotlin.Any?!> & EnumerableAssert & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Comparable<*> & java.io.Serializable..kotlin.Comparable<*>? & java.io.Serializable?>..AbstractAssert & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Any..kotlin.Any?!>? & EnumerableAssert & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Comparable<*> & java.io.Serializable..kotlin.Comparable<*>? & java.io.Serializable?>?, out kotlin.Any..kotlin.Any?!> & EnumerableAssert & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Any..kotlin.Any?!> & EnumerableAssert & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Comparable<*> & java.io.Serializable..kotlin.Comparable<*>? & java.io.Serializable?>..AbstractAssert & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Any..kotlin.Any?!>? & EnumerableAssert & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Comparable<*> & java.io.Serializable..kotlin.Comparable<*>? & java.io.Serializable?>?, out kotlin.Comparable & java.io.Serializable..kotlin.Comparable? & java.io.Serializable?>..AbstractAssert & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Any..kotlin.Any?!> & EnumerableAssert & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Comparable<*> & java.io.Serializable..kotlin.Comparable<*>? & java.io.Serializable?>..AbstractAssert & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Any..kotlin.Any?!>? & EnumerableAssert & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Comparable<*> & java.io.Serializable..kotlin.Comparable<*>? & java.io.Serializable?>?, out kotlin.Any..kotlin.Any?!>? & EnumerableAssert & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Any..kotlin.Any?!> & EnumerableAssert & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Comparable<*> & java.io.Serializable..kotlin.Comparable<*>? & java.io.Serializable?>..AbstractAssert & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Any..kotlin.Any?!>? & EnumerableAssert & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Comparable<*> & java.io.Serializable..kotlin.Comparable<*>? & java.io.Serializable?>?, out kotlin.Comparable & java.io.Serializable..kotlin.Comparable? & java.io.Serializable?>?, out kotlin.Any..kotlin.Any?!> & EnumerableAssert & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Any..kotlin.Any?!> & EnumerableAssert & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Comparable<*> & java.io.Serializable..kotlin.Comparable<*>? & java.io.Serializable?>..AbstractAssert & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Any..kotlin.Any?!>? & EnumerableAssert & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Comparable<*> & java.io.Serializable..kotlin.Comparable<*>? & java.io.Serializable?>?, out kotlin.Any..kotlin.Any?!> & EnumerableAssert & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Any..kotlin.Any?!> & EnumerableAssert & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Comparable<*> & java.io.Serializable..kotlin.Comparable<*>? & java.io.Serializable?>..AbstractAssert & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Any..kotlin.Any?!>? & EnumerableAssert & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Comparable<*> & java.io.Serializable..kotlin.Comparable<*>? & java.io.Serializable?>?, out kotlin.Comparable & java.io.Serializable..kotlin.Comparable? & java.io.Serializable?>..AbstractAssert & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Any..kotlin.Any?!> & EnumerableAssert & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Comparable<*> & java.io.Serializable..kotlin.Comparable<*>? & java.io.Serializable?>..AbstractAssert & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Any..kotlin.Any?!>? & EnumerableAssert & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Comparable<*> & java.io.Serializable..kotlin.Comparable<*>? & java.io.Serializable?>?, out kotlin.Any..kotlin.Any?!>? & EnumerableAssert & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Any..kotlin.Any?!> & EnumerableAssert & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Comparable<*> & java.io.Serializable..kotlin.Comparable<*>? & java.io.Serializable?>..AbstractAssert & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Any..kotlin.Any?!>? & EnumerableAssert & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Comparable<*> & java.io.Serializable..kotlin.Comparable<*>? & java.io.Serializable?>?, out kotlin.Comparable & java.io.Serializable..kotlin.Comparable? & java.io.Serializable?>?, out kotlin.Comparable & java.io.Serializable..kotlin.Comparable? & java.io.Serializable?>..AbstractAssert & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Any..kotlin.Any?!> & EnumerableAssert & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Comparable<*> & java.io.Serializable..kotlin.Comparable<*>? & java.io.Serializable?>..AbstractAssert & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Any..kotlin.Any?!>? & EnumerableAssert & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Comparable<*> & java.io.Serializable..kotlin.Comparable<*>? & java.io.Serializable?>?, out kotlin.Any..kotlin.Any?!> & EnumerableAssert & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Any..kotlin.Any?!> & EnumerableAssert & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Comparable<*> & java.io.Serializable..kotlin.Comparable<*>? & java.io.Serializable?>..AbstractAssert & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Any..kotlin.Any?!>? & EnumerableAssert & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Comparable<*> & java.io.Serializable..kotlin.Comparable<*>? & java.io.Serializable?>?, out kotlin.Comparable & java.io.Serializable..kotlin.Comparable? & java.io.Serializable?>..AbstractAssert & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Any..kotlin.Any?!> & EnumerableAssert & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Comparable<*> & java.io.Serializable..kotlin.Comparable<*>? & java.io.Serializable?>..AbstractAssert & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Any..kotlin.Any?!>? & EnumerableAssert & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Comparable<*> & java.io.Serializable..kotlin.Comparable<*>? & java.io.Serializable?>?, out kotlin.Any..kotlin.Any?!>? & EnumerableAssert & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Any..kotlin.Any?!> & EnumerableAssert & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Comparable<*> & java.io.Serializable..kotlin.Comparable<*>? & java.io.Serializable?>..AbstractAssert & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Any..kotlin.Any?!>? & EnumerableAssert & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Comparable<*> & java.io.Serializable..kotlin.Comparable<*>? & java.io.Serializable?>?, out kotlin.Comparable & java.io.Serializable..kotlin.Comparable? & java.io.Serializable?>?, out kotlin.Any..kotlin.Any?!>? & EnumerableAssert & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Any..kotlin.Any?!> & EnumerableAssert & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Comparable<*> & java.io.Serializable..kotlin.Comparable<*>? & java.io.Serializable?>..AbstractAssert & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Any..kotlin.Any?!>? & EnumerableAssert & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Comparable<*> & java.io.Serializable..kotlin.Comparable<*>? & java.io.Serializable?>?, out kotlin.Any..kotlin.Any?!> & EnumerableAssert & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Any..kotlin.Any?!> & EnumerableAssert & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Comparable<*> & java.io.Serializable..kotlin.Comparable<*>? & java.io.Serializable?>..AbstractAssert & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Any..kotlin.Any?!>? & EnumerableAssert & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Comparable<*> & java.io.Serializable..kotlin.Comparable<*>? & java.io.Serializable?>?, out kotlin.Comparable & java.io.Serializable..kotlin.Comparable? & java.io.Serializable?>..AbstractAssert & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Any..kotlin.Any?!> & EnumerableAssert & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Comparable<*> & java.io.Serializable..kotlin.Comparable<*>? & java.io.Serializable?>..AbstractAssert & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Any..kotlin.Any?!>? & EnumerableAssert & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Comparable<*> & java.io.Serializable..kotlin.Comparable<*>? & java.io.Serializable?>?, out kotlin.Any..kotlin.Any?!>? & EnumerableAssert & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Any..kotlin.Any?!> & EnumerableAssert & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Comparable<*> & java.io.Serializable..kotlin.Comparable<*>? & java.io.Serializable?>..AbstractAssert & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Any..kotlin.Any?!>? & EnumerableAssert & EnumerableAssert<*, *>..AbstractAssert<*, *>? & EnumerableAssert<*, *>?, out kotlin.Comparable<*> & java.io.Serializable..kotlin.Comparable<*>? & java.io.Serializable?>?, out kotlin.Comparable & java.io.Serializable..kotlin.Comparable? & java.io.Serializable?>?, out kotlin.Comparable & java.io.Serializable..kotlin.Comparable? & java.io.Serializable?>?")!>assertion } diff --git a/compiler/testData/diagnostics/testsWithStdLib/java/assertThatOnMap.kt b/compiler/testData/diagnostics/testsWithStdLib/java/assertThatOnMap.kt new file mode 100644 index 00000000000..c13f2189d8b --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/java/assertThatOnMap.kt @@ -0,0 +1,36 @@ +// FIR_IDENTICAL +// SKIP_TXT +// FILE: AbstractMapAssert.java + +import java.util.Map; + +public abstract class AbstractMapAssert, ACTUAL extends Map, K, V> { + public SELF isNotNull() { + return (SELF) this; + } +} + +// FILE: MapAssert.java + +import java.util.Map; + +public class MapAssert extends AbstractMapAssert, Map, KEY, VALUE> { + + public MapAssert(Map actual) {} +} + +// FILE: Assertions.java + +import java.util.Map; + +public class Assertions { + public static MapAssert assertThat(Map actual) { + return new MapAssert<>(actual); + } +} + +// FILE: test.kt + +fun > S?.must() { + Assertions.assertThat(this).isNotNull +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/purelyImplementedCollection/arrayList.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/purelyImplementedCollection/arrayList.fir.kt index 93a854b424e..77729128a3a 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/purelyImplementedCollection/arrayList.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/purelyImplementedCollection/arrayList.fir.kt @@ -5,18 +5,18 @@ fun bar(): String? = null fun foo() { var x = ArrayList() - x.add(null) - x.add(bar()) + x.add(null) + x.add(bar()) x.add("") - x[0] = null - x[0] = bar() + x[0] = null + x[0] = bar() x[0] = "" - val b1: MutableList = x + val b1: MutableList = x val b2: MutableList = x val b3: List = x val b4: Collection = x - val b6: MutableCollection = x -} \ No newline at end of file + val b6: MutableCollection = x +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/purelyImplementedCollection/arrayListNullable.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/purelyImplementedCollection/arrayListNullable.fir.kt index 9dca302f648..fa61a059260 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/purelyImplementedCollection/arrayListNullable.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/purelyImplementedCollection/arrayListNullable.fir.kt @@ -14,7 +14,7 @@ fun foo() { x[0] = "" val b1: MutableList = x - val b2: MutableList = x + val b2: MutableList = x val b3: List = x val b4: Collection = x diff --git a/compiler/testData/diagnostics/testsWithStdLib/purelyImplementedCollection/customClassMutableCollection.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/purelyImplementedCollection/customClassMutableCollection.fir.kt index 0f94c65da85..135766e6c25 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/purelyImplementedCollection/customClassMutableCollection.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/purelyImplementedCollection/customClassMutableCollection.fir.kt @@ -28,5 +28,5 @@ fun foo() { x.add("") val b1: Collection = x - val b2: MutableCollection = x + val b2: MutableCollection = x } diff --git a/compiler/testData/diagnostics/testsWithStdLib/purelyImplementedCollection/customClassMutableList.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/purelyImplementedCollection/customClassMutableList.fir.kt index 6790c181614..e5138150a0b 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/purelyImplementedCollection/customClassMutableList.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/purelyImplementedCollection/customClassMutableList.fir.kt @@ -31,10 +31,10 @@ fun foo() { x[0] = bar() x[0] = "" - val b1: MutableList = x + val b1: MutableList = x val b2: MutableList = x val b3: List = x val b4: Collection = x - val b6: MutableCollection = x + val b6: MutableCollection = x } diff --git a/compiler/testData/diagnostics/testsWithStdLib/purelyImplementedCollection/sets.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/purelyImplementedCollection/sets.fir.kt index ba7f62a8ac0..4ef593c4b3b 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/purelyImplementedCollection/sets.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/purelyImplementedCollection/sets.fir.kt @@ -7,30 +7,30 @@ fun bar(): String? = null fun fooHashSet() { var x = HashSet() - x.add(null) - x.add(bar()) + x.add(null) + x.add(bar()) x.add("") - val b1: MutableSet = x + val b1: MutableSet = x val b2: MutableSet = x val b3: Set = x val b4: Collection = x - val b6: MutableCollection = x + val b6: MutableCollection = x } fun fooTreeSet() { var x = TreeSet() - x.add(null) - x.add(bar()) + x.add(null) + x.add(bar()) x.add("") - val b1: MutableSet = x + val b1: MutableSet = x val b2: MutableSet = x val b3: Set = x val b4: Collection = x - val b6: MutableCollection = x + val b6: MutableCollection = x } fun fooLinkedHashSet() { @@ -39,10 +39,10 @@ fun fooLinkedHashSet() { x.add(bar()) x.add("") - val b1: MutableSet = x + val b1: MutableSet = x val b2: MutableSet = x val b3: Set = x val b4: Collection = x - val b6: MutableCollection = x + val b6: MutableCollection = x } diff --git a/compiler/testData/ir/irText/firProblems/AbstractMutableMap.fir.ir.txt b/compiler/testData/ir/irText/firProblems/AbstractMutableMap.fir.ir.txt index 7bcf65f6e00..07a908105fd 100644 --- a/compiler/testData/ir/irText/firProblems/AbstractMutableMap.fir.ir.txt +++ b/compiler/testData/ir/irText/firProblems/AbstractMutableMap.fir.ir.txt @@ -34,11 +34,11 @@ FILE fqName: fileName:/AbstractMutableMap.kt overridden: public open fun clear (): kotlin.Unit [fake_override] declared in kotlin.collections.AbstractMutableMap $this: VALUE_PARAMETER name: type:java.util.AbstractMap - FUN FAKE_OVERRIDE name:putAll visibility:public modality:OPEN <> ($this:java.util.AbstractMap, p0:@[EnhancedNullability] kotlin.collections.Map.MyMap?, out @[FlexibleNullability] V of .MyMap?>) returnType:kotlin.Unit [fake_override] + FUN FAKE_OVERRIDE name:putAll visibility:public modality:OPEN <> ($this:java.util.AbstractMap, p0:@[EnhancedNullability] kotlin.collections.Map.MyMap?, @[FlexibleNullability] V of .MyMap?>) returnType:kotlin.Unit [fake_override] overridden: public open fun putAll (p0: @[EnhancedNullability] kotlin.collections.Map): kotlin.Unit [fake_override] declared in kotlin.collections.AbstractMutableMap $this: VALUE_PARAMETER name: type:java.util.AbstractMap - VALUE_PARAMETER name:p0 index:0 type:@[EnhancedNullability] kotlin.collections.Map.MyMap?, out @[FlexibleNullability] V of .MyMap?> + VALUE_PARAMETER name:p0 index:0 type:@[EnhancedNullability] kotlin.collections.Map.MyMap?, @[FlexibleNullability] V of .MyMap?> FUN FAKE_OVERRIDE name:remove visibility:public modality:OPEN <> ($this:java.util.AbstractMap, p0:@[FlexibleNullability] K of .MyMap?) returnType:V of .MyMap? [fake_override] overridden: public open fun remove (p0: @[FlexibleNullability] K of kotlin.collections.AbstractMutableMap?): V of kotlin.collections.AbstractMutableMap? [fake_override] declared in kotlin.collections.AbstractMutableMap @@ -74,12 +74,12 @@ FILE fqName: fileName:/AbstractMutableMap.kt public open fun replaceAll (p0: @[EnhancedNullability] java.util.function.BiFunction): kotlin.Unit [fake_override] declared in kotlin.collections.AbstractMutableMap $this: VALUE_PARAMETER name: type:kotlin.collections.MutableMap VALUE_PARAMETER name:p0 index:0 type:@[EnhancedNullability] java.util.function.BiFunction.MyMap, in @[EnhancedNullability] V of .MyMap, out @[EnhancedNullability] V of .MyMap> - FUN FAKE_OVERRIDE name:merge visibility:public modality:OPEN <> ($this:kotlin.collections.MutableMap, p0:@[EnhancedNullability] K of .MyMap, p1:@[EnhancedNullability] V of .MyMap, p2:@[EnhancedNullability] java.util.function.BiFunction.MyMap, in @[EnhancedNullability] V of .MyMap, out V of .MyMap?>) returnType:V of .MyMap? [fake_override] + FUN FAKE_OVERRIDE name:merge visibility:public modality:OPEN <> ($this:kotlin.collections.MutableMap, p0:@[EnhancedNullability] K of .MyMap, p1:@[EnhancedNullability] {V of .MyMap & Any}, p2:@[EnhancedNullability] java.util.function.BiFunction.MyMap, in @[EnhancedNullability] V of .MyMap, out V of .MyMap?>) returnType:V of .MyMap? [fake_override] overridden: public open fun merge (p0: @[EnhancedNullability] K of kotlin.collections.AbstractMutableMap, p1: @[EnhancedNullability] {V of kotlin.collections.AbstractMutableMap & Any}, p2: @[EnhancedNullability] java.util.function.BiFunction): V of kotlin.collections.AbstractMutableMap? [fake_override] declared in kotlin.collections.AbstractMutableMap $this: VALUE_PARAMETER name: type:kotlin.collections.MutableMap VALUE_PARAMETER name:p0 index:0 type:@[EnhancedNullability] K of .MyMap - VALUE_PARAMETER name:p1 index:1 type:@[EnhancedNullability] V of .MyMap + VALUE_PARAMETER name:p1 index:1 type:@[EnhancedNullability] {V of .MyMap & Any} VALUE_PARAMETER name:p2 index:2 type:@[EnhancedNullability] java.util.function.BiFunction.MyMap, in @[EnhancedNullability] V of .MyMap, out V of .MyMap?> FUN FAKE_OVERRIDE name:computeIfPresent visibility:public modality:OPEN <> ($this:kotlin.collections.MutableMap, p0:@[EnhancedNullability] K of .MyMap, p1:@[EnhancedNullability] java.util.function.BiFunction.MyMap, in @[EnhancedNullability] V of .MyMap, out V of .MyMap?>) returnType:V of .MyMap? [fake_override] overridden: diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java index adf624f01ff..3c4aae973f0 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java @@ -18170,6 +18170,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/j+k/flexibleNothing.kt"); } + @Test + @TestMetadata("flexibleTypeVariablePosition.kt") + public void testFlexibleTypeVariablePosition() throws Exception { + runTest("compiler/testData/diagnostics/tests/j+k/flexibleTypeVariablePosition.kt"); + } + @Test @TestMetadata("genericConstructorWithMultipleBounds.kt") public void testGenericConstructorWithMultipleBounds() throws Exception { @@ -19193,6 +19199,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/j+k/types/typeParameter.kt"); } + @Test + @TestMetadata("upperBoundsCheckAgainstSelfTypeInJava.kt") + public void testUpperBoundsCheckAgainstSelfTypeInJava() throws Exception { + runTest("compiler/testData/diagnostics/tests/j+k/types/upperBoundsCheckAgainstSelfTypeInJava.kt"); + } + @Test @TestMetadata("varargOverride.kt") public void testVarargOverride() throws Exception { @@ -23116,6 +23128,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/platformTypes/samConstructor.kt"); } + @Test + @TestMetadata("starProjectionToFlexibleVariable.kt") + public void testStarProjectionToFlexibleVariable() throws Exception { + runTest("compiler/testData/diagnostics/tests/platformTypes/starProjectionToFlexibleVariable.kt"); + } + @Test @TestMetadata("supertypeTypeArguments.kt") public void testSupertypeTypeArguments() throws Exception { @@ -38018,6 +38036,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithStdLib/java"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true); } + @Test + @TestMetadata("assertThatOnMap.kt") + public void testAssertThatOnMap() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/java/assertThatOnMap.kt"); + } + @Test @TestMetadata("checkEnhancedUpperBounds.kt") public void testCheckEnhancedUpperBounds() throws Exception { diff --git a/core/compiler.common/src/org/jetbrains/kotlin/types/model/TypeSystemContext.kt b/core/compiler.common/src/org/jetbrains/kotlin/types/model/TypeSystemContext.kt index 076621648ed..c6dd7cd1c4f 100644 --- a/core/compiler.common/src/org/jetbrains/kotlin/types/model/TypeSystemContext.kt +++ b/core/compiler.common/src/org/jetbrains/kotlin/types/model/TypeSystemContext.kt @@ -289,15 +289,19 @@ interface TypeSystemInferenceExtensionContext : TypeSystemContext, TypeSystemBui } /** - * For case Foo <: (T..T?) return LowerBound for new constraint LowerBound <: T - * In FE 1.0, in case nullable it was just Foo?, so constraint was Foo? <: T + * For case Foo <: (T..T?) return LowerConstraint for new constraint LowerConstraint <: T + * In K1, in case nullable it was just Foo?, so constraint was Foo? <: T * But it's not 100% correct because prevent having not-nullable upper constraint on T while initial (Foo? <: (T..T?)) is not violated * - * In FIR, we try to have a correct one: (Foo!!..Foo?) <: T + * In FIR, we try to have a correct one: (Foo & Any..Foo?) <: T + * + * The same logic applies for T! <: UpperConstraint, as well + * In K1, it was reduced to T <: UpperConstraint..UpperConstraint? + * In FIR, we use UpperConstraint & Any..UpperConstraint? * * In future once we have only FIR (or FE 1.0 behavior is fixed) this method should be inlined to the use-site */ - fun SimpleTypeMarker.createConstraintPartForLowerBoundAndFlexibleTypeVariable(): KotlinTypeMarker + fun useRefinedBoundsForTypeVariableInFlexiblePosition(): Boolean fun createCapturedStarProjectionForSelfType( typeVariable: TypeVariableTypeConstructorMarker, diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/checker/ClassicTypeSystemContext.kt b/core/descriptors/src/org/jetbrains/kotlin/types/checker/ClassicTypeSystemContext.kt index fc3f153ad83..91bc4443973 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/checker/ClassicTypeSystemContext.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/checker/ClassicTypeSystemContext.kt @@ -25,6 +25,7 @@ import org.jetbrains.kotlin.resolve.substitutedUnderlyingType import org.jetbrains.kotlin.resolve.unsubstitutedUnderlyingType import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.error.ErrorTypeKind +import org.jetbrains.kotlin.types.error.ErrorUtils import org.jetbrains.kotlin.types.model.* import org.jetbrains.kotlin.types.typeUtil.* import org.jetbrains.kotlin.utils.addIfNotNull @@ -33,7 +34,6 @@ import org.jetbrains.kotlin.utils.addToStdlib.safeAs import org.jetbrains.kotlin.types.typeUtil.isSignedOrUnsignedNumberType as classicIsSignedOrUnsignedNumberType import org.jetbrains.kotlin.types.typeUtil.isStubType as isSimpleTypeStubType import org.jetbrains.kotlin.types.typeUtil.isStubTypeForBuilderInference as isSimpleTypeStubTypeForBuilderInference -import org.jetbrains.kotlin.types.error.ErrorUtils import org.jetbrains.kotlin.types.typeUtil.isStubTypeForVariableInSubtyping as isSimpleTypeStubTypeForVariableInSubtyping interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSystemCommonBackendContext { @@ -876,12 +876,7 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSy return (baseType.memberScope as? SubstitutingScope)?.substitutor } - override fun SimpleTypeMarker.createConstraintPartForLowerBoundAndFlexibleTypeVariable(): KotlinTypeMarker = - if (this.isMarkedNullable()) { - this - } else { - createFlexibleType(this, this.withNullability(true)) - } + override fun useRefinedBoundsForTypeVariableInFlexiblePosition(): Boolean = false override fun substitutionSupertypePolicy(type: SimpleTypeMarker): TypeCheckerState.SupertypesPolicy { require(type is SimpleType, type::errorMessage)