From f70ae2df3ace432a6401d3d48d6fb3d50efc9ac8 Mon Sep 17 00:00:00 2001 From: "Denis.Zharkov" Date: Tue, 12 Apr 2022 16:30:55 +0300 Subject: [PATCH] FIR: Refine inference constraints when type variable in flexible position That issue might be fixed via changing TypeVariableMarker.shouldBeFlexible at ConeConstraintSystemUtilContext but this and some other tricks have been added because of incorrect handling of constraints where type variable has a flexible bound ^KT-51168 Fixed --- ...CompilerTestFE10TestdataTestGenerated.java | 24 ++++++++ .../resolve/arguments/lambdaInLambda2.fir.txt | 2 +- .../typeMismatchOnExpectedJavaMap.fir.txt | 2 +- .../resolve/defaultJavaImportHiding.fir.txt | 4 +- .../expresssions/genericDiagnostic.fir.txt | 4 +- .../flexibleTypeBug.fir.txt | 2 +- .../flexibleTypeVarAgainstNull.fir.txt | 2 +- .../samConstructors/genericSam.fir.txt | 2 +- ...ublicJavaAndPrivateKotlinVar.overrides.txt | 4 +- .../resolve/smartcasts/kt50788.fir.txt | 2 +- .../types/typeAliasInArguments.fir.txt | 2 +- .../concurrentMapOfAliases.fir.txt | 4 +- .../j+k/flexibleTypeAliases.fir.txt | 2 +- .../javaLangComparator.fir.txt | 2 +- .../kotlinComparatorAlias.fir.txt | 2 +- .../problems/weakHashMap.fir.txt | 4 +- .../typeAliasWithForEach.fir.txt | 4 +- ...irOldFrontendDiagnosticsTestGenerated.java | 24 ++++++++ ...DiagnosticsWithLightTreeTestGenerated.java | 24 ++++++++ .../kotlin/fir/java/JavaTypeConversion.kt | 14 ++++- .../fir/java/enhancement/javaTypeUtils.kt | 13 ++-- .../fir/resolve/substitution/Substitutors.kt | 10 ++-- .../kotlin/fir/types/ConeInferenceContext.kt | 3 +- .../kotlin/fir/types/ConeTypeContext.kt | 20 +++++-- .../jetbrains/kotlin/fir/types/TypeUtils.kt | 7 ++- ...CreateFreshTypeVariableSubstitutorStage.kt | 30 +--------- .../ConeConstraintSystemUtilContext.kt | 3 +- .../components/ConstraintIncorporator.kt | 6 +- .../TypeCheckerStateForConstraintSystem.kt | 60 +++++++++++++++---- .../jspecify/strictMode/Captured.fir.kt | 17 ------ .../jspecify/strictMode/Captured.kt | 1 + .../java8Tests/misc/returnType.fir.kt | 2 +- .../misc/returnTypeWithWarnings.fir.kt | 2 +- .../overridesJavaAnnotated.fir.kt | 42 +++++++++++++ .../overridesJavaAnnotated.kt | 1 - .../tests/inference/findViewById.fir.kt | 2 +- .../j+k/flexibleTypeVariablePosition.fir.kt | 20 +++++++ .../tests/j+k/flexibleTypeVariablePosition.kt | 20 +++++++ .../upperBoundsCheckAgainstSelfTypeInJava.kt | 11 ++++ .../methodTypeParameter.fir.kt | 2 +- .../platformTypes/nullableTypeArgument.fir.kt | 9 --- .../platformTypes/nullableTypeArgument.kt | 1 + .../starProjectionToFlexibleVariable.kt | 20 +++++++ .../recursiveFlexibleAssertions.fir.kt | 2 +- .../testsWithStdLib/java/assertThatOnMap.kt | 36 +++++++++++ .../arrayList.fir.kt | 14 ++--- .../arrayListNullable.fir.kt | 2 +- .../customClassMutableCollection.fir.kt | 2 +- .../customClassMutableList.fir.kt | 4 +- .../purelyImplementedCollection/sets.fir.kt | 20 +++---- .../firProblems/AbstractMutableMap.fir.ir.txt | 8 +-- .../test/runners/DiagnosticTestGenerated.java | 24 ++++++++ .../kotlin/types/model/TypeSystemContext.kt | 12 ++-- .../types/checker/ClassicTypeSystemContext.kt | 9 +-- 54 files changed, 411 insertions(+), 154 deletions(-) delete mode 100644 compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/strictMode/Captured.fir.kt create mode 100644 compiler/testData/diagnostics/tests/explicitDefinitelyNotNullableViaIntersection/overridesJavaAnnotated.fir.kt create mode 100644 compiler/testData/diagnostics/tests/j+k/flexibleTypeVariablePosition.fir.kt create mode 100644 compiler/testData/diagnostics/tests/j+k/flexibleTypeVariablePosition.kt create mode 100644 compiler/testData/diagnostics/tests/j+k/types/upperBoundsCheckAgainstSelfTypeInJava.kt delete mode 100644 compiler/testData/diagnostics/tests/platformTypes/nullableTypeArgument.fir.kt create mode 100644 compiler/testData/diagnostics/tests/platformTypes/starProjectionToFlexibleVariable.kt create mode 100644 compiler/testData/diagnostics/testsWithStdLib/java/assertThatOnMap.kt 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)