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 741bdf7af23..6fa6041d23e 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 @@ -35694,6 +35694,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag runTest("compiler/testData/diagnostics/testsWithStdLib/builderInference/resolveUsualCallWithBuilderInferenceWithRestrictions.kt"); } + @Test + @TestMetadata("typeVariableShouldNotBeFixed.kt") + public void testTypeVariableShouldNotBeFixed() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/builderInference/typeVariableShouldNotBeFixed.kt"); + } + @Test @TestMetadata("useInferenceInformationFromExtension.kt") public void testUseInferenceInformationFromExtension() throws Exception { 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 c619546737b..e8188080598 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 @@ -35694,6 +35694,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti runTest("compiler/testData/diagnostics/testsWithStdLib/builderInference/resolveUsualCallWithBuilderInferenceWithRestrictions.kt"); } + @Test + @TestMetadata("typeVariableShouldNotBeFixed.kt") + public void testTypeVariableShouldNotBeFixed() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/builderInference/typeVariableShouldNotBeFixed.kt"); + } + @Test @TestMetadata("useInferenceInformationFromExtension.kt") public void testUseInferenceInformationFromExtension() 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 464cd7bff9f..10a71bd29b9 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 @@ -35694,6 +35694,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac runTest("compiler/testData/diagnostics/testsWithStdLib/builderInference/resolveUsualCallWithBuilderInferenceWithRestrictions.kt"); } + @Test + @TestMetadata("typeVariableShouldNotBeFixed.kt") + public void testTypeVariableShouldNotBeFixed() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/builderInference/typeVariableShouldNotBeFixed.kt"); + } + @Test @TestMetadata("useInferenceInformationFromExtension.kt") public void testUseInferenceInformationFromExtension() throws Exception { diff --git a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/VariableFixationFinder.kt b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/VariableFixationFinder.kt index ee8faf02f7e..1396f0ea3fb 100644 --- a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/VariableFixationFinder.kt +++ b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/VariableFixationFinder.kt @@ -204,9 +204,15 @@ class VariableFixationFinder( inline fun TypeSystemInferenceExtensionContext.isProperTypeForFixation(type: KotlinTypeMarker, isProper: (KotlinTypeMarker) -> Boolean) = isProper(type) && extractProjectionsForAllCapturedTypes(type).all(isProper) -@OptIn(ExperimentalStdlibApi::class) fun TypeSystemInferenceExtensionContext.extractProjectionsForAllCapturedTypes(baseType: KotlinTypeMarker): Set { - val simpleBaseType = baseType.asSimpleType() + if (baseType.isFlexible()) { + val flexibleType = baseType.asFlexibleType()!! + return buildSet { + addAll(extractProjectionsForAllCapturedTypes(flexibleType.lowerBound())) + addAll(extractProjectionsForAllCapturedTypes(flexibleType.upperBound())) + } + } + val simpleBaseType = baseType.asSimpleType()?.originalIfDefinitelyNotNullable() return buildSet { val projectionType = if (simpleBaseType is CapturedTypeMarker) { diff --git a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/model/NewConstraintSystemImpl.kt b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/model/NewConstraintSystemImpl.kt index 77c38c779ec..8c6f50b3840 100644 --- a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/model/NewConstraintSystemImpl.kt +++ b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/model/NewConstraintSystemImpl.kt @@ -289,7 +289,7 @@ class NewConstraintSystemImpl( private fun isProperTypeImpl(type: KotlinTypeMarker): Boolean = !type.contains { val capturedType = it.asSimpleType()?.asCapturedType() - // TODO: change NewCapturedType to markered one for FE-IR + val typeToCheck = if (capturedType is CapturedTypeMarker && capturedType.captureStatus() == CaptureStatus.FROM_EXPRESSION) capturedType.typeConstructorProjection().takeUnless { projection -> projection.isStarProjection() }?.getType() else diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/NewTypeSubstitutor.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/NewTypeSubstitutor.kt index 6f1b4f79e37..5196f72a420 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/NewTypeSubstitutor.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/NewTypeSubstitutor.kt @@ -117,7 +117,8 @@ interface NewTypeSubstitutor : TypeSubstitutorMarker { TypeProjectionImpl(typeConstructor.projection.projectionKind, substitutedInnerType), typeParameter = typeConstructor.typeParameter ).also { it.initializeSupertypes(substitutedSuperTypes) }, - lowerType = if (capturedType.lowerType != null) substitutedInnerType else null + lowerType = if (capturedType.lowerType != null) substitutedInnerType else null, + isMarkedNullable = type.isMarkedNullable ) } } diff --git a/compiler/testData/diagnostics/testsWithStdLib/builderInference/typeVariableShouldNotBeFixed.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/builderInference/typeVariableShouldNotBeFixed.fir.kt new file mode 100644 index 00000000000..a9f6f0453fe --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/builderInference/typeVariableShouldNotBeFixed.fir.kt @@ -0,0 +1,32 @@ +// FILE: spr/Expr.java +package spr; + +import org.jetbrains.annotations.NotNull; + +public interface Exec { + boolean run(@NotNull Model model, @NotNull Processor params); +} + +// FILE: spr/foo.kt +package spr + +open class Processor

{ + fun process(t: P): Boolean { + return true + } +} + +class Model + +fun context(p: Processor, exec: Exec) {} + +fun materialize(): Processor = TODO() + +private fun foo(model: Model) { + materialize().apply { + context( + this, + Exec { m, p -> p.process(m) } // Note: Builder inference + ) + } +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/builderInference/typeVariableShouldNotBeFixed.kt b/compiler/testData/diagnostics/testsWithStdLib/builderInference/typeVariableShouldNotBeFixed.kt new file mode 100644 index 00000000000..cdc0f55611f --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/builderInference/typeVariableShouldNotBeFixed.kt @@ -0,0 +1,32 @@ +// FILE: spr/Expr.java +package spr; + +import org.jetbrains.annotations.NotNull; + +public interface Exec { + boolean run(@NotNull Model model, @NotNull Processor params); +} + +// FILE: spr/foo.kt +package spr + +open class Processor

{ + fun process(t: P): Boolean { + return true + } +} + +class Model + +fun context(p: Processor, exec: Exec) {} + +fun materialize(): Processor = TODO() + +private fun foo(model: Model) { + materialize().apply { + context( + this, + Exec { m, p -> p.process(m) } // Note: Builder inference + ) + } +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/builderInference/typeVariableShouldNotBeFixed.txt b/compiler/testData/diagnostics/testsWithStdLib/builderInference/typeVariableShouldNotBeFixed.txt new file mode 100644 index 00000000000..7b808472473 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/builderInference/typeVariableShouldNotBeFixed.txt @@ -0,0 +1,29 @@ +package + +package spr { + public fun context(/*0*/ p: spr.Processor, /*1*/ exec: spr.Exec): kotlin.Unit + private fun foo(/*0*/ model: spr.Model): kotlin.Unit + public fun materialize(): spr.Processor + + public interface Exec { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public abstract fun run(/*0*/ @org.jetbrains.annotations.NotNull model: spr.Model, /*1*/ @org.jetbrains.annotations.NotNull params: spr.Processor): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } + + public final class Model { + public constructor Model() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } + + public open class Processor { + public constructor Processor() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public final fun process(/*0*/ t: P): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } +} 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 da8b10a29a0..049f6a05eac 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 @@ -35784,6 +35784,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/testsWithStdLib/builderInference/resolveUsualCallWithBuilderInferenceWithRestrictions.kt"); } + @Test + @TestMetadata("typeVariableShouldNotBeFixed.kt") + public void testTypeVariableShouldNotBeFixed() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/builderInference/typeVariableShouldNotBeFixed.kt"); + } + @Test @TestMetadata("useInferenceInformationFromExtension.kt") public void testUseInferenceInformationFromExtension() throws Exception { 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 28997a49e70..0cb0c206d36 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/checker/ClassicTypeSystemContext.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/checker/ClassicTypeSystemContext.kt @@ -122,6 +122,7 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSy } override fun CapturedTypeMarker.lowerType(): KotlinTypeMarker? { + // TODO: https://youtrack.jetbrains.com/issue/KT-54196 (old captured type here) require(this is NewCapturedType, this::errorMessage) return this.lowerType } diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/flexibleTypes.kt b/core/descriptors/src/org/jetbrains/kotlin/types/flexibleTypes.kt index f98e42ca14d..bc2db357cf6 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/flexibleTypes.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/flexibleTypes.kt @@ -101,6 +101,7 @@ class FlexibleTypeImpl(lowerBound: SimpleType, upperBound: SimpleType) : Flexibl assert(!lowerBound.isFlexible()) { "Lower bound of a flexible type can not be flexible: $lowerBound" } assert(!upperBound.isFlexible()) { "Upper bound of a flexible type can not be flexible: $upperBound" } + // TODO: https://youtrack.jetbrains.com/issue/KT-54198 (two captured types) assert(lowerBound != upperBound) { "Lower and upper bounds are equal: $lowerBound == $upperBound" } assert(KotlinTypeChecker.DEFAULT.isSubtypeOf(lowerBound, upperBound)) { "Lower bound $lowerBound of a flexible type must be a subtype of the upper bound $upperBound"