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 3cd70d5d0c7..7421df8dce5 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 @@ -12638,12 +12638,6 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/inference/builderInference"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true); } - @Test - @TestMetadata("renderingStubTypes.kt") - public void testRenderingStubTypes() throws Exception { - runTest("compiler/testData/diagnostics/tests/inference/builderInference/renderingStubTypes.kt"); - } - @Test @TestMetadata("simpleLambdaInCallWithAnotherLambdaWithBuilderInference.kt") public void testSimpleLambdaInCallWithAnotherLambdaWithBuilderInference() throws Exception { @@ -12691,6 +12685,64 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti public void testSpecialCallsWithLambdas() throws Exception { runTest("compiler/testData/diagnostics/tests/inference/builderInference/specialCallsWithLambdas.kt"); } + + @Nested + @TestMetadata("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes") + @TestDataPath("$PROJECT_ROOT") + public class StubTypes { + @Test + public void testAllFilesPresentInStubTypes() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true); + } + + @Test + @TestMetadata("capturedTypes.kt") + public void testCapturedTypes() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/capturedTypes.kt"); + } + + @Test + @TestMetadata("commonSuperType.kt") + public void testCommonSuperType() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperType.kt"); + } + + @Test + @TestMetadata("commonSuperTypeContravariant.kt") + public void testCommonSuperTypeContravariant() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperTypeContravariant.kt"); + } + + @Test + @TestMetadata("commonSuperTypeCovariant.kt") + public void testCommonSuperTypeCovariant() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperTypeCovariant.kt"); + } + + @Test + @TestMetadata("commonSuperTypeInvariant.kt") + public void testCommonSuperTypeInvariant() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperTypeInvariant.kt"); + } + + @Test + @TestMetadata("commonSuperTypeNullable.kt") + public void testCommonSuperTypeNullable() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperTypeNullable.kt"); + } + + @Test + @TestMetadata("intersect.kt") + public void testIntersect() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/intersect.kt"); + } + + @Test + @TestMetadata("renderingStubTypes.kt") + public void testRenderingStubTypes() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/renderingStubTypes.kt"); + } + } } @Nested 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 a21bb339dcd..bccf25fecea 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 @@ -12638,12 +12638,6 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/inference/builderInference"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true); } - @Test - @TestMetadata("renderingStubTypes.kt") - public void testRenderingStubTypes() throws Exception { - runTest("compiler/testData/diagnostics/tests/inference/builderInference/renderingStubTypes.kt"); - } - @Test @TestMetadata("simpleLambdaInCallWithAnotherLambdaWithBuilderInference.kt") public void testSimpleLambdaInCallWithAnotherLambdaWithBuilderInference() throws Exception { @@ -12691,6 +12685,64 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac public void testSpecialCallsWithLambdas() throws Exception { runTest("compiler/testData/diagnostics/tests/inference/builderInference/specialCallsWithLambdas.kt"); } + + @Nested + @TestMetadata("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes") + @TestDataPath("$PROJECT_ROOT") + public class StubTypes { + @Test + public void testAllFilesPresentInStubTypes() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true); + } + + @Test + @TestMetadata("capturedTypes.kt") + public void testCapturedTypes() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/capturedTypes.kt"); + } + + @Test + @TestMetadata("commonSuperType.kt") + public void testCommonSuperType() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperType.kt"); + } + + @Test + @TestMetadata("commonSuperTypeContravariant.kt") + public void testCommonSuperTypeContravariant() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperTypeContravariant.kt"); + } + + @Test + @TestMetadata("commonSuperTypeCovariant.kt") + public void testCommonSuperTypeCovariant() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperTypeCovariant.kt"); + } + + @Test + @TestMetadata("commonSuperTypeInvariant.kt") + public void testCommonSuperTypeInvariant() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperTypeInvariant.kt"); + } + + @Test + @TestMetadata("commonSuperTypeNullable.kt") + public void testCommonSuperTypeNullable() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperTypeNullable.kt"); + } + + @Test + @TestMetadata("intersect.kt") + public void testIntersect() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/intersect.kt"); + } + + @Test + @TestMetadata("renderingStubTypes.kt") + public void testRenderingStubTypes() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/renderingStubTypes.kt"); + } + } } @Nested diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeInferenceContext.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeInferenceContext.kt index ca5e4478281..c2e2906a39b 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeInferenceContext.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeInferenceContext.kt @@ -256,6 +256,9 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo return ConeStubType(typeVariable, ConeNullability.create(typeVariable.defaultType().isMarkedNullable())) } + // TODO + override fun createStubTypeForTypeVariablesInSubtyping(typeVariable: TypeVariableMarker) = createStubType(typeVariable) + override fun KotlinTypeMarker.removeAnnotations(): KotlinTypeMarker { require(this is ConeKotlinType) return withAttributes(ConeAttributes.Empty, this@ConeInferenceContext) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt index 5b2b6676fbe..7ee598c64c2 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt @@ -380,7 +380,11 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty } override fun SimpleTypeMarker.isStubType(): Boolean { - return this is StubTypeMarker + return this is ConeStubType // TODO: distinguish stub types for builder inference and for subtyping + } + + override fun SimpleTypeMarker.isStubTypeForVariableInSubtyping(): Boolean { + return this is ConeStubType // TODO: distinguish stub types for builder inference and for subtyping } override fun intersectTypes(types: List): SimpleTypeMarker { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/BuilderInferenceSession.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/BuilderInferenceSession.kt index 6616c8e16c1..92cadb3aab4 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/BuilderInferenceSession.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/BuilderInferenceSession.kt @@ -29,8 +29,10 @@ import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver import org.jetbrains.kotlin.resolve.descriptorUtil.hasBuilderInferenceAnnotation import org.jetbrains.kotlin.types.* +import org.jetbrains.kotlin.types.checker.NewCapturedType import org.jetbrains.kotlin.types.expressions.DoubleColonExpressionResolver import org.jetbrains.kotlin.types.expressions.ExpressionTypingServices +import org.jetbrains.kotlin.types.typeUtil.asTypeProjection import org.jetbrains.kotlin.types.typeUtil.contains import org.jetbrains.kotlin.utils.addToStdlib.cast @@ -146,6 +148,16 @@ class BuilderInferenceSession( return null } + @OptIn(ExperimentalStdlibApi::class) + private fun findAllParentBuildInferenceSessions() = buildList { + var currentSession: BuilderInferenceSession? = findParentBuildInferenceSession() + + while (currentSession != null) { + add(currentSession) + currentSession = currentSession.findParentBuildInferenceSession() + } + } + fun hasInapplicableCall(): Boolean = hasInapplicableCall override fun writeOnlyStubs(callInfo: SingleCallResolutionResult): Boolean { @@ -257,6 +269,10 @@ class BuilderInferenceSession( ): Boolean { storage.notFixedTypeVariables.values.forEach { commonSystem.registerVariable(it.typeVariable) } + for (parentSession in findAllParentBuildInferenceSessions()) { + parentSession.stubsForPostponedVariables.keys.forEach { commonSystem.registerVariable(it) } + } + /* * storage can contain the following substitutions: * TypeVariable(A) -> ProperType @@ -269,8 +285,10 @@ class BuilderInferenceSession( var introducedConstraint = false for (initialConstraint in storage.initialConstraints) { - val lower = nonFixedToVariablesSubstitutor.safeSubstitute(callSubstitutor.safeSubstitute(initialConstraint.a as UnwrappedType)) // TODO: SUB - val upper = nonFixedToVariablesSubstitutor.safeSubstitute(callSubstitutor.safeSubstitute(initialConstraint.b as UnwrappedType)) // TODO: SUB + val lowerCallSubstituted = callSubstitutor.safeSubstitute(initialConstraint.a as UnwrappedType) + val upperCallSubstituted = callSubstitutor.safeSubstitute(initialConstraint.b as UnwrappedType) + + val (lower, upper) = substituteNotFixedVariables(lowerCallSubstituted, upperCallSubstituted, nonFixedToVariablesSubstitutor) if (commonSystem.isProperType(lower) && commonSystem.isProperType(upper)) continue @@ -301,6 +319,39 @@ class BuilderInferenceSession( return introducedConstraint } + private fun substituteNotFixedVariables( + lowerType: KotlinType, + upperType: KotlinType, + nonFixedToVariablesSubstitutor: NewTypeSubstitutor + ): Pair { + val commonCapTypes = extractCommonCapturedTypes(lowerType, upperType) + val substitutedCommonCapType = commonCapTypes.associate { + it.constructor as TypeConstructor to nonFixedToVariablesSubstitutor.safeSubstitute(it).asTypeProjection() + } + + val capTypesSubstitutor = TypeConstructorSubstitution.createByConstructorsMap(substitutedCommonCapType).buildSubstitutor() + + val substitutedLowerType = nonFixedToVariablesSubstitutor.safeSubstitute(capTypesSubstitutor.substitute(lowerType.unwrap())) + val substitutedUpperType = nonFixedToVariablesSubstitutor.safeSubstitute(capTypesSubstitutor.substitute(upperType.unwrap())) + + return substitutedLowerType to substitutedUpperType + } + + private fun extractCommonCapturedTypes(a: KotlinType, b: KotlinType): List { + val extractedCapturedTypes = mutableSetOf().also { extractCapturedTypes(a, it) } + return extractedCapturedTypes.filter { capturedType -> b.contains { it.constructor === capturedType.constructor } } + } + + private fun extractCapturedTypes(type: KotlinType, capturedTypes: MutableSet) { + if (type is NewCapturedType) { + capturedTypes.add(type) + } + for (typeArgument in type.arguments) { + if (typeArgument.isStarProjection) continue + extractCapturedTypes(typeArgument.type, capturedTypes) + } + } + private fun buildCommonSystem(initialStorage: ConstraintStorage): Pair { val commonSystem = NewConstraintSystemImpl(callComponents.constraintInjector, builtIns) diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSystemContext.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSystemContext.kt index 87d07ddd05d..1d26021fe55 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSystemContext.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSystemContext.kt @@ -51,6 +51,8 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon override fun SimpleTypeMarker.isStubType() = false + override fun SimpleTypeMarker.isStubTypeForVariableInSubtyping() = false + override fun FlexibleTypeMarker.asDynamicType() = this as? IrDynamicType override fun FlexibleTypeMarker.asRawType(): RawTypeMarker? = null @@ -394,8 +396,13 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon override fun createErrorTypeWithCustomConstructor(debugName: String, constructor: TypeConstructorMarker): KotlinTypeMarker = TODO("IrTypeSystemContext doesn't support constraint system resolution") - override fun nullableAnyType(): SimpleTypeMarker = - irBuiltIns.anyNType as IrSimpleType + override fun nullableAnyType() = irBuiltIns.anyNType as IrSimpleType + + override fun nullableNothingType() = irBuiltIns.nothingNType as IrSimpleType + + override fun nothingType() = irBuiltIns.nothingType as IrSimpleType + + override fun anyType() = irBuiltIns.anyType as IrSimpleType override fun arrayType(componentType: KotlinTypeMarker): SimpleTypeMarker = irBuiltIns.arrayClass.typeWith(componentType as IrType) diff --git a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/NewCommonSuperTypeCalculator.kt b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/NewCommonSuperTypeCalculator.kt index b98a365de9d..f1ba7f38293 100644 --- a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/NewCommonSuperTypeCalculator.kt +++ b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/NewCommonSuperTypeCalculator.kt @@ -59,7 +59,7 @@ object NewCommonSuperTypeCalculator { if (!isTopLevelType) { val nonStubTypes = - types.filter { !isStubRelatedType(it.lowerBoundIfFlexible()) && !isStubRelatedType(it.upperBoundIfFlexible()) } + types.filter { !isTypeVariable(it.lowerBoundIfFlexible()) && !isTypeVariable(it.upperBoundIfFlexible()) } val equalToEachOtherTypes = nonStubTypes.filter { potentialCommonSuperType -> nonStubTypes.all { AbstractTypeChecker.equalTypes(this, it, potentialCommonSuperType) @@ -87,7 +87,7 @@ object NewCommonSuperTypeCalculator { // i.e. result type also should be marked nullable val notAllNotNull = - types.any { !isStubRelatedType(it) && !AbstractNullabilityChecker.isSubtypeOfAny(contextStubTypesEqualToAnything, it) } + types.any { !isTypeVariable(it) && !AbstractNullabilityChecker.isSubtypeOfAny(contextStubTypesEqualToAnything, it) } val notNullTypes = if (notAllNotNull) types.map { it.withNullability(false) } else types val commonSuperType = commonSuperTypeForNotNullTypes(notNullTypes, depth, contextStubTypesEqualToAnything, contextStubTypesNotEqual) @@ -164,14 +164,23 @@ object NewCommonSuperTypeCalculator { ): SimpleTypeMarker { if (types.size == 1) return types.single() - val nonStubTypes = types.filter { !isStubRelatedType(it) } - if (nonStubTypes.size == 1) return nonStubTypes.single() + val nonTypeVariables = types.filter { !isTypeVariable(it) } + if (nonTypeVariables.size == 1) return nonTypeVariables.single() - assert(nonStubTypes.isNotEmpty()) { + assert(nonTypeVariables.isNotEmpty()) { "There should be at least one non-stub type to compute common supertype but there are: $types" } - val uniqueTypes = uniquify(nonStubTypes, contextStubTypesNotEqual) + val stubTypeVariables = types.filter { isStubTypeVariable(it) } + val nonStubTypeVariables = types.filter { !isStubTypeVariable(it) } + val areAllNonStubTypesNothing = nonStubTypeVariables.isNotEmpty() && nonStubTypeVariables.all { it.isNothing() } + if (nonStubTypeVariables.size == 1 && !areAllNonStubTypesNothing) return nonStubTypeVariables.single() + + if (nonStubTypeVariables.isEmpty() || areAllNonStubTypesNothing) { + return uniquify(stubTypeVariables, contextStubTypesNotEqual).singleOrNull() ?: nullableAnyType() + } + + val uniqueTypes = uniquify(nonTypeVariables, contextStubTypesNotEqual) if (uniqueTypes.size == 1) return uniqueTypes.single() val explicitSupertypes = filterSupertypes(uniqueTypes, contextStubTypesNotEqual) @@ -183,16 +192,26 @@ object NewCommonSuperTypeCalculator { return findSuperTypeConstructorsAndIntersectResult(explicitSupertypes, depth, contextStubTypesEqualToAnything) } - private fun TypeSystemCommonSuperTypesContext.isStubRelatedType(type: SimpleTypeMarker): Boolean { - return type.isStubType() || isCapturedStubType(type) + private fun TypeSystemCommonSuperTypesContext.isStubTypeVariable(type: SimpleTypeMarker): Boolean { + return type.isStubType() || isStubCapturedTypeVariable(type) } - private fun TypeSystemCommonSuperTypesContext.isCapturedStubType(type: SimpleTypeMarker): Boolean { + private fun TypeSystemCommonSuperTypesContext.isStubCapturedTypeVariable(type: SimpleTypeMarker): Boolean { val projectedType = type.asCapturedType()?.typeConstructor()?.projection()?.takeUnless { it.isStarProjection() }?.getType() ?: return false return projectedType.asSimpleType()?.isStubType() == true } + private fun TypeSystemCommonSuperTypesContext.isTypeVariable(type: SimpleTypeMarker): Boolean { + return type.isStubTypeForVariableInSubtyping() || isCapturedTypeVariable(type) + } + + private fun TypeSystemCommonSuperTypesContext.isCapturedTypeVariable(type: SimpleTypeMarker): Boolean { + val projectedType = + type.asCapturedType()?.typeConstructor()?.projection()?.takeUnless { it.isStarProjection() }?.getType() ?: return false + return projectedType.asSimpleType()?.isStubTypeForVariableInSubtyping() == true + } + private fun TypeSystemCommonSuperTypesContext.findErrorTypeInSupertypes( types: List, contextStubTypesEqualToAnything: AbstractTypeCheckerContext @@ -288,7 +307,7 @@ object NewCommonSuperTypeCalculator { null } - typeArgument.getType().lowerBoundIfFlexible().isStubType() -> null + typeArgument.getType().lowerBoundIfFlexible().isStubTypeForVariableInSubtyping() -> null else -> typeArgument } diff --git a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/InferenceUtils.kt b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/InferenceUtils.kt index 64a886535b9..03b695ccc01 100644 --- a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/InferenceUtils.kt +++ b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/InferenceUtils.kt @@ -43,6 +43,6 @@ fun ConstraintStorage.buildNotFixedVariablesToNonSubtypableTypesSubstitutor( context: TypeSystemInferenceExtensionContext ): TypeSubstitutorMarker { return context.typeSubstitutorByTypeConstructor( - notFixedTypeVariables.mapValues { context.createStubType(it.value.typeVariable) } + notFixedTypeVariables.mapValues { context.createStubTypeForTypeVariablesInSubtyping(it.value.typeVariable) } ) } diff --git a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/ResultTypeResolver.kt b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/ResultTypeResolver.kt index be9d87e9c87..d4c4cd752cc 100644 --- a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/ResultTypeResolver.kt +++ b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/ResultTypeResolver.kt @@ -134,15 +134,13 @@ class ResultTypeResolver( val types = sinkIntegerLiteralTypes(lowerConstraintTypes) var commonSuperType = computeCommonSuperType(types) - if (commonSuperType.contains { it is StubTypeMarker }) { + if (commonSuperType.contains { it.asSimpleType()?.isStubTypeForVariableInSubtyping() == true }) { val typesWithoutStubs = types.filter { lowerType -> - !lowerType.contains { it is StubTypeMarker } + !lowerType.contains { it.asSimpleType()?.isStubTypeForVariableInSubtyping() == true } } if (typesWithoutStubs.isNotEmpty()) { commonSuperType = computeCommonSuperType(typesWithoutStubs) - } else { - return null } } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ClassicTypeSystemContextForCS.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ClassicTypeSystemContextForCS.kt index 026b0232b30..21699b7a18a 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ClassicTypeSystemContextForCS.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ClassicTypeSystemContextForCS.kt @@ -77,6 +77,13 @@ class ClassicTypeSystemContextForCS(override val builtIns: KotlinBuiltIns) : Typ return StubType(typeVariable.freshTypeConstructor() as TypeConstructor, typeVariable.defaultType().isMarkedNullable()) } + override fun createStubTypeForTypeVariablesInSubtyping(typeVariable: TypeVariableMarker): StubTypeMarker { + return StubTypeForTypeVariablesInSubtyping( + typeVariable.freshTypeConstructor() as TypeConstructor, + typeVariable.defaultType().isMarkedNullable() + ) + } + override fun TypeConstructorMarker.isTypeVariable(): Boolean { return this is TypeVariableTypeConstructor } diff --git a/compiler/testData/diagnostics/tests/inference/builderInference/specialCallsWithCallableReferences.kt b/compiler/testData/diagnostics/tests/inference/builderInference/specialCallsWithCallableReferences.kt index 8a8b670b894..5a36cdeb617 100644 --- a/compiler/testData/diagnostics/tests/inference/builderInference/specialCallsWithCallableReferences.kt +++ b/compiler/testData/diagnostics/tests/inference/builderInference/specialCallsWithCallableReferences.kt @@ -39,7 +39,7 @@ fun select(vararg x: R) = x[0] fun poll0(): Flow { return flow { val inv = select(::bar, ::foo) - inv() + inv() } } @@ -144,7 +144,7 @@ fun poll17(flag: Boolean): Flow { fun poll2(flag: Boolean): Flow { return flow { val inv = when (flag) { true -> ::bar else -> ::foo } - inv() + inv() } } @@ -193,7 +193,7 @@ fun poll26(flag: Boolean): Flow { fun poll3(flag: Boolean): Flow { return flow { val inv = when (flag) { true -> ::bar false -> ::foo } - inv() + inv() } } diff --git a/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/capturedTypes.fir.kt b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/capturedTypes.fir.kt new file mode 100644 index 00000000000..1200f7a5985 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/capturedTypes.fir.kt @@ -0,0 +1,44 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER -DEPRECATION -UNCHECKED_CAST -EXPERIMENTAL_IS_NOT_ENABLED -UNUSED_VARIABLE +// WITH_RUNTIME + +// FILE: main.kt +import kotlin.experimental.ExperimentalTypeInference + +@UseExperimental(ExperimentalTypeInference::class) +fun build(@BuilderInference block: TestInterface.() -> Unit): R = TODO() + +@UseExperimental(ExperimentalTypeInference::class) +fun build2(@BuilderInference block: TestInterface.() -> Unit): R = TODO() + +interface TestInterface { + fun emit(r: R) + fun get(): R + fun getInv(): Inv + fun getOut(): Inv + fun getIn(): Inv +} + +class Inv + +fun captureOut(x: Inv): K = null as K +fun captureIn(x: Inv): K = null as K +fun capture(x: Inv): K = null as K + +fun main() { + build { + emit("") + getInv() + captureOut(getInv()) + captureIn(getInv()) + + // K is fixed into CapturedType(out NotFixed: TypeVariable(R)) + capture(getOut()) + "" + } + build { + emit("") + // K is fixed into CapturedType(in NotFixed: TypeVariable(R)) + capture(getIn()) + "" + } +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/capturedTypes.kt b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/capturedTypes.kt new file mode 100644 index 00000000000..77499321355 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/capturedTypes.kt @@ -0,0 +1,44 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER -DEPRECATION -UNCHECKED_CAST -EXPERIMENTAL_IS_NOT_ENABLED -UNUSED_VARIABLE +// WITH_RUNTIME + +// FILE: main.kt +import kotlin.experimental.ExperimentalTypeInference + +@UseExperimental(ExperimentalTypeInference::class) +fun build(@BuilderInference block: TestInterface.() -> Unit): R = TODO() + +@UseExperimental(ExperimentalTypeInference::class) +fun build2(@BuilderInference block: TestInterface.() -> Unit): R = TODO() + +interface TestInterface { + fun emit(r: R) + fun get(): R + fun getInv(): Inv + fun getOut(): Inv + fun getIn(): Inv +} + +class Inv + +fun captureOut(x: Inv): K = null as K +fun captureIn(x: Inv): K = null as K +fun capture(x: Inv): K = null as K + +fun main() { + build { + emit("") + ")!>getInv() + captureOut(")!>getInv()) + captureIn(")!>getInv()) + + // K is fixed into CapturedType(out NotFixed: TypeVariable(R)) + capture(")!>getOut()) + "" + } + build { + emit("") + // K is fixed into CapturedType(in NotFixed: TypeVariable(R)) + capture(")!>getIn()) + "" + } +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/capturedTypes.txt b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/capturedTypes.txt new file mode 100644 index 00000000000..84f85769a70 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/capturedTypes.txt @@ -0,0 +1,26 @@ +package + +@kotlin.UseExperimental(markerClass = {kotlin.experimental.ExperimentalTypeInference::class}) public fun build(/*0*/ @kotlin.BuilderInference block: TestInterface.() -> kotlin.Unit): R +@kotlin.UseExperimental(markerClass = {kotlin.experimental.ExperimentalTypeInference::class}) public fun build2(/*0*/ @kotlin.BuilderInference block: TestInterface.() -> kotlin.Unit): R +public fun capture(/*0*/ x: Inv): K +public fun captureIn(/*0*/ x: Inv): K +public fun captureOut(/*0*/ x: Inv): K +public fun main(): kotlin.Unit + +public final class Inv { + public constructor Inv() + 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 interface TestInterface { + public abstract fun emit(/*0*/ r: R): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract fun get(): R + public abstract fun getIn(): Inv + public abstract fun getInv(): Inv + public abstract fun getOut(): Inv + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperType.fir.kt b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperType.fir.kt new file mode 100644 index 00000000000..cc5f6ce7d99 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperType.fir.kt @@ -0,0 +1,56 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER -DEPRECATION -EXPERIMENTAL_IS_NOT_ENABLED -UNUSED_VARIABLE +// WITH_RUNTIME + +// FILE: Test.java + +class Test { + static T foo(T x) { return x; } +} + +// FILE: main.kt +import kotlin.experimental.ExperimentalTypeInference + +@UseExperimental(ExperimentalTypeInference::class) +fun build(@BuilderInference block: TestInterface.() -> Unit): R = TODO() + +@UseExperimental(ExperimentalTypeInference::class) +fun build2(@BuilderInference block: TestInterface.() -> Unit): R = TODO() + +class Inv + +interface TestInterface { + fun emit(r: R) + fun get(): R + fun getInv(): Inv +} + +fun id(x: U) = x +fun select(vararg x: E) = x[0] + +fun test() { + val ret = build { + emit("1") + Test.foo(get()) + Test.foo(getInv()) + id(get()) + select(get(), get()) + select(Test.foo(get()), Test.foo(get())) + select(Test.foo(get()), get()) + select(getInv(), getInv()) + select(Test.foo(getInv()), Test.foo(getInv())) + select(Test.foo(getInv()), getInv()) + select(getInv(), Test.foo(getInv())) + select(id(get()), id(get())) + build2 { + emit(1) + select(this@build.get(), get()) + select(Test.foo(this@build.get()), Test.foo(get())) + select(this@build.getInv(), getInv()) + select(Test.foo(this@build.getInv()), Test.foo(getInv())) + select(Test.foo(this@build.getInv()), getInv()) + select(id(this@build.get()), id(get())) + "" + } + "" + } +} diff --git a/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperType.kt b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperType.kt new file mode 100644 index 00000000000..84005ec4c2e --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperType.kt @@ -0,0 +1,56 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER -DEPRECATION -EXPERIMENTAL_IS_NOT_ENABLED -UNUSED_VARIABLE +// WITH_RUNTIME + +// FILE: Test.java + +class Test { + static T foo(T x) { return x; } +} + +// FILE: main.kt +import kotlin.experimental.ExperimentalTypeInference + +@UseExperimental(ExperimentalTypeInference::class) +fun build(@BuilderInference block: TestInterface.() -> Unit): R = TODO() + +@UseExperimental(ExperimentalTypeInference::class) +fun build2(@BuilderInference block: TestInterface.() -> Unit): R = TODO() + +class Inv + +interface TestInterface { + fun emit(r: R) + fun get(): R + fun getInv(): Inv +} + +fun id(x: U) = x +fun select(vararg x: E) = x[0] + +fun test() { + val ret = build { + emit("1") + Test.foo(get()) + ..Inv?)")!>Test.foo(getInv()) + id(get()) + select(get(), get()) + select(Test.foo(get()), Test.foo(get())) + select(Test.foo(get()), get()) + ")!>select(getInv(), getInv()) + ..Inv?)")!>select(Test.foo(getInv()), Test.foo(getInv())) + ..Inv?)")!>select(Test.foo(getInv()), getInv()) + ..Inv?)")!>select(getInv(), Test.foo(getInv())) + select(id(get()), id(get())) + build2 { + emit(1) + select(this@build.get(), get()) + select(Test.foo(this@build.get()), Test.foo(get())) + ")!>select(this@build.getInv(), getInv()) + ..Inv?)")!>select(Test.foo(this@build.getInv()), Test.foo(getInv())) + ..Inv?)")!>select(Test.foo(this@build.getInv()), getInv()) + select(id(this@build.get()), id(get())) + "" + } + "" + } +} diff --git a/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperType.txt b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperType.txt new file mode 100644 index 00000000000..fdf2c29c0dd --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperType.txt @@ -0,0 +1,33 @@ +package + +@kotlin.UseExperimental(markerClass = {kotlin.experimental.ExperimentalTypeInference::class}) public fun build(/*0*/ @kotlin.BuilderInference block: TestInterface.() -> kotlin.Unit): R +@kotlin.UseExperimental(markerClass = {kotlin.experimental.ExperimentalTypeInference::class}) public fun build2(/*0*/ @kotlin.BuilderInference block: TestInterface.() -> kotlin.Unit): R +public fun id(/*0*/ x: U): U +public fun select(/*0*/ vararg x: E /*kotlin.Array*/): E +public fun test(): kotlin.Unit + +public final class Inv { + public constructor Inv() + 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/*package*/ open class Test { + public/*package*/ constructor Test() + 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 + + // Static members + public/*package*/ open fun foo(/*0*/ x: T!): T! +} + +public interface TestInterface { + public abstract fun emit(/*0*/ r: R): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract fun get(): R + public abstract fun getInv(): Inv + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperTypeContravariant.fir.kt b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperTypeContravariant.fir.kt new file mode 100644 index 00000000000..6b77f81ebe9 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperTypeContravariant.fir.kt @@ -0,0 +1,83 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER -DEPRECATION -EXPERIMENTAL_IS_NOT_ENABLED -UNUSED_VARIABLE +// WITH_RUNTIME + +// FILE: Test.java + +class Test { + static T foo(T x) { return x; } +} + +// FILE: main.kt +import kotlin.experimental.ExperimentalTypeInference + +@UseExperimental(ExperimentalTypeInference::class) +fun build(@BuilderInference block: TestInterface.() -> Unit): R1 = TODO() + +@UseExperimental(ExperimentalTypeInference::class) +fun build2(@BuilderInference block: TestInterface.() -> Unit): R2 = TODO() + +class In + +interface TestInterface { + fun emit(r: R) + fun get(): R + fun getIn(): In +} + +fun id(x: U): U? = x +fun select1(x: E, y: In): E? = x +fun select2(x: E, y: In): E = x +fun select3(x: E?, y: In): E = x!! +fun select4(x: E?, y: In): E = x!! + +fun test() { + val ret = build { + emit("1") + select1(get(), getIn()) + select1(get(), Test.foo(getIn())) + select1(Test.foo(get()), Test.foo(getIn())) + select1(Test.foo(get()), getIn()) + select4(get(), getIn()) + select4(get(), Test.foo(getIn())) + select4(Test.foo(get()), Test.foo(getIn())) + select4(Test.foo(get()), getIn()) + + select4(id(Test.foo(get())), getIn()) + + build2 { + emit(1) + select1(this@build.get(), getIn()) + select1(get(), Test.foo(this@build.getIn())) + select1(Test.foo(this@build.get()), Test.foo(getIn())) + select1(Test.foo(get()), this@build.getIn()) + select2(this@build.get(), getIn()) + select2(get(), Test.foo(this@build.getIn())) + select2(Test.foo(this@build.get()), Test.foo(getIn())) + select2(Test.foo(get()), this@build.getIn()) + select3(this@build.get(), getIn()) + select3(get(), Test.foo(this@build.getIn())) + select3(Test.foo(this@build.get()), Test.foo(getIn())) + select3(Test.foo(get()), this@build.getIn()) + select4(this@build.get(), getIn()) + select4(get(), Test.foo(this@build.getIn())) + select4(Test.foo(this@build.get()), Test.foo(getIn())) + select4(Test.foo(get()), this@build.getIn()) + + select4(id(Test.foo(this@build.get())), getIn()) + "" + } + "" + } + val ret2 = build { + emit(if (true) "" else null) + select2(get(), getIn()) + select2(get(), Test.foo(getIn())) + select2(Test.foo(get()), Test.foo(getIn())) + select2(Test.foo(get()), getIn()) + select3(get(), getIn()) + select3(get(), Test.foo(getIn())) + select3(Test.foo(get()), Test.foo(getIn())) + select3(Test.foo(get()), getIn()) + "" + } +} diff --git a/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperTypeContravariant.kt b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperTypeContravariant.kt new file mode 100644 index 00000000000..831ce4c760d --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperTypeContravariant.kt @@ -0,0 +1,83 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER -DEPRECATION -EXPERIMENTAL_IS_NOT_ENABLED -UNUSED_VARIABLE +// WITH_RUNTIME + +// FILE: Test.java + +class Test { + static T foo(T x) { return x; } +} + +// FILE: main.kt +import kotlin.experimental.ExperimentalTypeInference + +@UseExperimental(ExperimentalTypeInference::class) +fun build(@BuilderInference block: TestInterface.() -> Unit): R1 = TODO() + +@UseExperimental(ExperimentalTypeInference::class) +fun build2(@BuilderInference block: TestInterface.() -> Unit): R2 = TODO() + +class In + +interface TestInterface { + fun emit(r: R) + fun get(): R + fun getIn(): In +} + +fun id(x: U): U? = x +fun select1(x: E, y: In): E? = x +fun select2(x: E, y: In): E = x +fun select3(x: E?, y: In): E = x!! +fun select4(x: E?, y: In): E = x!! + +fun test() { + val ret = build { + emit("1") + select1(get(), getIn()) + select1(get(), Test.foo(getIn())) + select1(Test.foo(get()), Test.foo(getIn())) + select1(Test.foo(get()), getIn()) + select4(get(), getIn()) + select4(get(), Test.foo(getIn())) + select4(Test.foo(get()), Test.foo(getIn())) + select4(Test.foo(get()), getIn()) + + select4(id(Test.foo(get())), getIn()) + + build2 { + emit(1) + select1(this@build.get(), getIn()) + select1(get(), Test.foo(this@build.getIn())) + select1(Test.foo(this@build.get()), Test.foo(getIn())) + select1(Test.foo(get()), this@build.getIn()) + select2(this@build.get(), getIn()) + select2(get(), Test.foo(this@build.getIn())) + select2(Test.foo(this@build.get()), Test.foo(getIn())) + select2(Test.foo(get()), this@build.getIn()) + select3(this@build.get(), getIn()) + select3(get(), Test.foo(this@build.getIn())) + select3(Test.foo(this@build.get()), Test.foo(getIn())) + select3(Test.foo(get()), this@build.getIn()) + select4(this@build.get(), getIn()) + select4(get(), Test.foo(this@build.getIn())) + select4(Test.foo(this@build.get()), Test.foo(getIn())) + select4(Test.foo(get()), this@build.getIn()) + + select4(id(Test.foo(this@build.get())), getIn()) + "" + } + "" + } + val ret2 = build { + emit(if (true) "" else null) + select2(get(), getIn()) + select2(get(), Test.foo(getIn())) + select2(Test.foo(get()), Test.foo(getIn())) + select2(Test.foo(get()), getIn()) + select3(get(), getIn()) + select3(get(), Test.foo(getIn())) + select3(Test.foo(get()), Test.foo(getIn())) + select3(Test.foo(get()), getIn()) + "" + } +} diff --git a/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperTypeContravariant.txt b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperTypeContravariant.txt new file mode 100644 index 00000000000..6270a2eec95 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperTypeContravariant.txt @@ -0,0 +1,36 @@ +package + +@kotlin.UseExperimental(markerClass = {kotlin.experimental.ExperimentalTypeInference::class}) public fun build(/*0*/ @kotlin.BuilderInference block: TestInterface.() -> kotlin.Unit): R1 +@kotlin.UseExperimental(markerClass = {kotlin.experimental.ExperimentalTypeInference::class}) public fun build2(/*0*/ @kotlin.BuilderInference block: TestInterface.() -> kotlin.Unit): R2 +public fun id(/*0*/ x: U): U? +public fun select1(/*0*/ x: E, /*1*/ y: In): E? +public fun select2(/*0*/ x: E, /*1*/ y: In): E +public fun select3(/*0*/ x: E?, /*1*/ y: In): E +public fun select4(/*0*/ x: E?, /*1*/ y: In): E +public fun test(): kotlin.Unit + +public final class In { + public constructor In() + 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/*package*/ open class Test { + public/*package*/ constructor Test() + 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 + + // Static members + public/*package*/ open fun foo(/*0*/ x: T!): T! +} + +public interface TestInterface { + public abstract fun emit(/*0*/ r: R): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract fun get(): R + public abstract fun getIn(): In + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperTypeCovariant.fir.kt b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperTypeCovariant.fir.kt new file mode 100644 index 00000000000..94e80b833a1 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperTypeCovariant.fir.kt @@ -0,0 +1,79 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER -DEPRECATION -EXPERIMENTAL_IS_NOT_ENABLED -UNUSED_VARIABLE +// WITH_RUNTIME + +// FILE: Test.java + +class Test { + static T foo(T x) { return x; } +} + +// FILE: main.kt +import kotlin.experimental.ExperimentalTypeInference + +@UseExperimental(ExperimentalTypeInference::class) +fun build(@BuilderInference block: TestInterface.() -> Unit): R1 = TODO() + +@UseExperimental(ExperimentalTypeInference::class) +fun build2(@BuilderInference block: TestInterface.() -> Unit): R2 = TODO() + +class Out + +interface TestInterface { + fun emit(r: R) + fun get(): R + fun getOut(): Out +} + +fun id(x: U): U? = x +fun select1(x: E, y: Out): E? = x +fun select2(x: E, y: Out): E = x +fun select3(x: E?, y: Out): E = x!! +fun select4(x: E?, y: Out): E = x!! + +fun test() { + val ret = build { + emit("1") + select1(get(), getOut()) + select1(get(), Test.foo(getOut())) + select1(Test.foo(get()), Test.foo(getOut())) + select1(Test.foo(get()), getOut()) + select2(get(), getOut()) + select2(get(), Test.foo(getOut())) + select2(Test.foo(get()), Test.foo(getOut())) + select2(Test.foo(get()), getOut()) + select3(get(), getOut()) + select3(get(), Test.foo(getOut())) + select3(Test.foo(get()), Test.foo(getOut())) + select3(Test.foo(get()), getOut()) + select4(get(), getOut()) + select4(get(), Test.foo(getOut())) + select4(Test.foo(get()), Test.foo(getOut())) + select4(Test.foo(get()), getOut()) + + select4(id(Test.foo(get())), getOut()) + + build2 { + emit(1) + select1(this@build.get(), getOut()) + select1(get(), Test.foo(this@build.getOut())) + select1(Test.foo(this@build.get()), Test.foo(getOut())) + select1(Test.foo(get()), this@build.getOut()) + select2(this@build.get(), getOut()) + select2(get(), Test.foo(this@build.getOut())) + select2(Test.foo(this@build.get()), Test.foo(getOut())) + select2(Test.foo(get()), this@build.getOut()) + select3(this@build.get(), getOut()) + select3(get(), Test.foo(this@build.getOut())) + select3(Test.foo(this@build.get()), Test.foo(getOut())) + select3(Test.foo(get()), this@build.getOut()) + select4(this@build.get(), getOut()) + select4(get(), Test.foo(this@build.getOut())) + select4(Test.foo(this@build.get()), Test.foo(getOut())) + select4(Test.foo(get()), this@build.getOut()) + + select4(id(Test.foo(this@build.get())), getOut()) + "" + } + "" + } +} diff --git a/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperTypeCovariant.kt b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperTypeCovariant.kt new file mode 100644 index 00000000000..4a349459ee5 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperTypeCovariant.kt @@ -0,0 +1,79 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER -DEPRECATION -EXPERIMENTAL_IS_NOT_ENABLED -UNUSED_VARIABLE +// WITH_RUNTIME + +// FILE: Test.java + +class Test { + static T foo(T x) { return x; } +} + +// FILE: main.kt +import kotlin.experimental.ExperimentalTypeInference + +@UseExperimental(ExperimentalTypeInference::class) +fun build(@BuilderInference block: TestInterface.() -> Unit): R1 = TODO() + +@UseExperimental(ExperimentalTypeInference::class) +fun build2(@BuilderInference block: TestInterface.() -> Unit): R2 = TODO() + +class Out + +interface TestInterface { + fun emit(r: R) + fun get(): R + fun getOut(): Out +} + +fun id(x: U): U? = x +fun select1(x: E, y: Out): E? = x +fun select2(x: E, y: Out): E = x +fun select3(x: E?, y: Out): E = x!! +fun select4(x: E?, y: Out): E = x!! + +fun test() { + val ret = build { + emit("1") + select1(get(), getOut()) + select1(get(), Test.foo(getOut())) + select1(Test.foo(get()), Test.foo(getOut())) + select1(Test.foo(get()), getOut()) + select2(get(), getOut()) + select2(get(), Test.foo(getOut())) + select2(Test.foo(get()), Test.foo(getOut())) + select2(Test.foo(get()), getOut()) + select3(get(), getOut()) + select3(get(), Test.foo(getOut())) + select3(Test.foo(get()), Test.foo(getOut())) + select3(Test.foo(get()), getOut()) + select4(get(), getOut()) + select4(get(), Test.foo(getOut())) + select4(Test.foo(get()), Test.foo(getOut())) + select4(Test.foo(get()), getOut()) + + select4(id(Test.foo(get())), getOut()) + + build2 { + emit(1) + select1(this@build.get(), getOut()) + select1(get(), Test.foo(this@build.getOut())) + select1(Test.foo(this@build.get()), Test.foo(getOut())) + select1(Test.foo(get()), this@build.getOut()) + select2(this@build.get(), getOut()) + select2(get(), Test.foo(this@build.getOut())) + select2(Test.foo(this@build.get()), Test.foo(getOut())) + select2(Test.foo(get()), this@build.getOut()) + select3(this@build.get(), getOut()) + select3(get(), Test.foo(this@build.getOut())) + select3(Test.foo(this@build.get()), Test.foo(getOut())) + select3(Test.foo(get()), this@build.getOut()) + select4(this@build.get(), getOut()) + select4(get(), Test.foo(this@build.getOut())) + select4(Test.foo(this@build.get()), Test.foo(getOut())) + select4(Test.foo(get()), this@build.getOut()) + + select4(id(Test.foo(this@build.get())), getOut()) + "" + } + "" + } +} diff --git a/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperTypeCovariant.txt b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperTypeCovariant.txt new file mode 100644 index 00000000000..c45431f64e7 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperTypeCovariant.txt @@ -0,0 +1,36 @@ +package + +@kotlin.UseExperimental(markerClass = {kotlin.experimental.ExperimentalTypeInference::class}) public fun build(/*0*/ @kotlin.BuilderInference block: TestInterface.() -> kotlin.Unit): R1 +@kotlin.UseExperimental(markerClass = {kotlin.experimental.ExperimentalTypeInference::class}) public fun build2(/*0*/ @kotlin.BuilderInference block: TestInterface.() -> kotlin.Unit): R2 +public fun id(/*0*/ x: U): U? +public fun select1(/*0*/ x: E, /*1*/ y: Out): E? +public fun select2(/*0*/ x: E, /*1*/ y: Out): E +public fun select3(/*0*/ x: E?, /*1*/ y: Out): E +public fun select4(/*0*/ x: E?, /*1*/ y: Out): E +public fun test(): kotlin.Unit + +public final class Out { + public constructor Out() + 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/*package*/ open class Test { + public/*package*/ constructor Test() + 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 + + // Static members + public/*package*/ open fun foo(/*0*/ x: T!): T! +} + +public interface TestInterface { + public abstract fun emit(/*0*/ r: R): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract fun get(): R + public abstract fun getOut(): Out + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperTypeInvariant.fir.kt b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperTypeInvariant.fir.kt new file mode 100644 index 00000000000..d9638659a73 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperTypeInvariant.fir.kt @@ -0,0 +1,89 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER -DEPRECATION -EXPERIMENTAL_IS_NOT_ENABLED -UNUSED_VARIABLE +// WITH_RUNTIME + +// FILE: Test.java + +class Test { + static T foo(T x) { return x; } +} + +// FILE: main.kt +import kotlin.experimental.ExperimentalTypeInference + +@UseExperimental(ExperimentalTypeInference::class) +fun build(@BuilderInference block: TestInterface.() -> Unit): R1 = TODO() + +@UseExperimental(ExperimentalTypeInference::class) +fun build2(@BuilderInference block: TestInterface.() -> Unit): R2 = TODO() + +class Inv + +interface TestInterface { + fun emit(r: R) + fun get(): R + fun getInv(): Inv +} + +fun id(x: U): U? = x +fun select1(x: E, y: Inv): E? = x +fun select2(x: E, y: Inv): E = x +fun select3(x: E?, y: Inv): E = x!! +fun select4(x: E?, y: Inv): E = x!! + +fun test() { + val ret1 = build { + emit("1") + select1(get(), getInv()) + select1(get(), Test.foo(getInv())) + select1(Test.foo(get()), Test.foo(getInv())) + select1(Test.foo(get()), getInv()) + select4(get(), getInv()) + select4(get(), Test.foo(getInv())) + select4(Test.foo(get()), Test.foo(getInv())) + select4(Test.foo(get()), getInv()) + + select4(id(Test.foo(get())), getInv()) + + build2 { + emit(1) + select1(this@build.get(), getInv()) + select1(get(), Test.foo(this@build.getInv())) + select1(Test.foo(this@build.get()), Test.foo(getInv())) + select1(Test.foo(get()), this@build.getInv()) + select4(this@build.get(), getInv()) + select4(get(), Test.foo(this@build.getInv())) + select4(Test.foo(this@build.get()), Test.foo(getInv())) + select4(Test.foo(get()), this@build.getInv()) + + select4(id(Test.foo(this@build.get())), getInv()) + "" + } + "" + } + + val ret2 = build { + emit(if (true) "1" else null) + select2(get(), getInv()) + select2(get(), Test.foo(getInv())) + select2(Test.foo(get()), Test.foo(getInv())) + select2(Test.foo(get()), getInv()) + select3(get(), getInv()) + select3(get(), Test.foo(getInv())) + select3(Test.foo(get()), Test.foo(getInv())) + select3(Test.foo(get()), getInv()) + + build2 { + emit(1) + select2(this@build.get(), getInv()) + select2(get(), Test.foo(this@build.getInv())) + select2(Test.foo(this@build.get()), Test.foo(getInv())) + select2(Test.foo(get()), this@build.getInv()) + select3(this@build.get(), getInv()) + select3(get(), Test.foo(this@build.getInv())) + select3(Test.foo(this@build.get()), Test.foo(getInv())) + select3(Test.foo(get()), this@build.getInv()) + "" + } + "" + } +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperTypeInvariant.kt b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperTypeInvariant.kt new file mode 100644 index 00000000000..dbeb6a091ab --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperTypeInvariant.kt @@ -0,0 +1,89 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER -DEPRECATION -EXPERIMENTAL_IS_NOT_ENABLED -UNUSED_VARIABLE +// WITH_RUNTIME + +// FILE: Test.java + +class Test { + static T foo(T x) { return x; } +} + +// FILE: main.kt +import kotlin.experimental.ExperimentalTypeInference + +@UseExperimental(ExperimentalTypeInference::class) +fun build(@BuilderInference block: TestInterface.() -> Unit): R1 = TODO() + +@UseExperimental(ExperimentalTypeInference::class) +fun build2(@BuilderInference block: TestInterface.() -> Unit): R2 = TODO() + +class Inv + +interface TestInterface { + fun emit(r: R) + fun get(): R + fun getInv(): Inv +} + +fun id(x: U): U? = x +fun select1(x: E, y: Inv): E? = x +fun select2(x: E, y: Inv): E = x +fun select3(x: E?, y: Inv): E = x!! +fun select4(x: E?, y: Inv): E = x!! + +fun test() { + val ret1 = build { + emit("1") + select1(get(), getInv()) + select1(get(), Test.foo(getInv())) + select1(Test.foo(get()), Test.foo(getInv())) + select1(Test.foo(get()), getInv()) + select4(get(), getInv()) + select4(get(), Test.foo(getInv())) + select4(Test.foo(get()), Test.foo(getInv())) + select4(Test.foo(get()), getInv()) + + select4(id(Test.foo(get())), getInv()) + + build2 { + emit(1) + select1(this@build.get(), getInv()) + select1(get(), Test.foo(this@build.getInv())) + select1(Test.foo(this@build.get()), Test.foo(getInv())) + select1(Test.foo(get()), this@build.getInv()) + select4(this@build.get(), getInv()) + select4(get(), Test.foo(this@build.getInv())) + select4(Test.foo(this@build.get()), Test.foo(getInv())) + select4(Test.foo(get()), this@build.getInv()) + + select4(id(Test.foo(this@build.get())), getInv()) + "" + } + "" + } + + val ret2 = build { + emit(if (true) "1" else null) + select2(get(), getInv()) + select2(get(), Test.foo(getInv())) + select2(Test.foo(get()), Test.foo(getInv())) + select2(Test.foo(get()), getInv()) + select3(get(), getInv()) + select3(get(), Test.foo(getInv())) + select3(Test.foo(get()), Test.foo(getInv())) + select3(Test.foo(get()), getInv()) + + build2 { + emit(1) + select2(this@build.get(), getInv()) + select2(get(), Test.foo(this@build.getInv())) + select2(Test.foo(this@build.get()), Test.foo(getInv())) + select2(Test.foo(get()), this@build.getInv()) + select3(this@build.get(), getInv()) + select3(get(), Test.foo(this@build.getInv())) + select3(Test.foo(this@build.get()), Test.foo(getInv())) + select3(Test.foo(get()), this@build.getInv()) + "" + } + "" + } +} diff --git a/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperTypeInvariant.txt b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperTypeInvariant.txt new file mode 100644 index 00000000000..56dacc97171 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperTypeInvariant.txt @@ -0,0 +1,36 @@ +package + +@kotlin.UseExperimental(markerClass = {kotlin.experimental.ExperimentalTypeInference::class}) public fun build(/*0*/ @kotlin.BuilderInference block: TestInterface.() -> kotlin.Unit): R1 +@kotlin.UseExperimental(markerClass = {kotlin.experimental.ExperimentalTypeInference::class}) public fun build2(/*0*/ @kotlin.BuilderInference block: TestInterface.() -> kotlin.Unit): R2 +public fun id(/*0*/ x: U): U? +public fun select1(/*0*/ x: E, /*1*/ y: Inv): E? +public fun select2(/*0*/ x: E, /*1*/ y: Inv): E +public fun select3(/*0*/ x: E?, /*1*/ y: Inv): E +public fun select4(/*0*/ x: E?, /*1*/ y: Inv): E +public fun test(): kotlin.Unit + +public final class Inv { + public constructor Inv() + 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/*package*/ open class Test { + public/*package*/ constructor Test() + 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 + + // Static members + public/*package*/ open fun foo(/*0*/ x: T!): T! +} + +public interface TestInterface { + public abstract fun emit(/*0*/ r: R): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract fun get(): R + public abstract fun getInv(): Inv + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperTypeNullable.fir.kt b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperTypeNullable.fir.kt new file mode 100644 index 00000000000..10efcd9533a --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperTypeNullable.fir.kt @@ -0,0 +1,81 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER -DEPRECATION -EXPERIMENTAL_IS_NOT_ENABLED -UNUSED_VARIABLE +// WITH_RUNTIME + +// FILE: Test.java + +import org.jetbrains.annotations.* + +class Test { + @Nullable + static T foo(T x) { return x; } +} + +// FILE: main.kt +import kotlin.experimental.ExperimentalTypeInference + +@UseExperimental(ExperimentalTypeInference::class) +fun build(@BuilderInference block: TestInterface.() -> Unit): R = TODO() + +@UseExperimental(ExperimentalTypeInference::class) +fun build2(@BuilderInference block: TestInterface.() -> Unit): R = TODO() + +class Inv + +interface TestInterface { + fun emit(r: R) + fun get(): R + fun getInv(): Inv +} + +fun id(x: U): U? = x +fun select(vararg x: E): E? = x[0] + +fun test() { + val ret = build { + emit("1") + Test.foo(get()) + Test.foo(getInv()) + id(get()) + select(get(), get()) + select(Test.foo(get()), Test.foo(get())) + select(Test.foo(get()), get()) + select(getInv(), getInv()) + select(Test.foo(getInv()), Test.foo(getInv())) + select(Test.foo(getInv()), getInv()) + select(getInv(), Test.foo(getInv())) + select(id(get()), id(get())) + build2 { + emit(1) + select(this@build.get(), get()) + select(Test.foo(this@build.get()), Test.foo(get())) + select(this@build.getInv(), getInv()) + select(Test.foo(this@build.getInv()), Test.foo(getInv())) + select(Test.foo(this@build.getInv()), getInv()) + select(id(this@build.get()), id(get())) + "" + } + "" + } + val ret2 = build { + emit("1") + select(get(), null) + select(Test.foo(null), Test.foo(get())) + select(Test.foo(get()), null) + select(null, getInv()) + select(Test.foo(getInv()), Test.foo(null)) + select(Test.foo(null), getInv()) + select(getInv(), Test.foo(null)) + select(id(null), id(get())) + build2 { + emit(1) + select(this@build.get(), get(), null) + select(Test.foo(this@build.get()), Test.foo(get()), null) + select(this@build.getInv(), getInv(), null) + select(Test.foo(this@build.getInv()), Test.foo(getInv()), null) + select(Test.foo(this@build.getInv()), getInv(), null) + select(id(this@build.get()), id(get()), null) + "" + } + "" + } +} diff --git a/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperTypeNullable.kt b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperTypeNullable.kt new file mode 100644 index 00000000000..0366c6643fc --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperTypeNullable.kt @@ -0,0 +1,81 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER -DEPRECATION -EXPERIMENTAL_IS_NOT_ENABLED -UNUSED_VARIABLE +// WITH_RUNTIME + +// FILE: Test.java + +import org.jetbrains.annotations.* + +class Test { + @Nullable + static T foo(T x) { return x; } +} + +// FILE: main.kt +import kotlin.experimental.ExperimentalTypeInference + +@UseExperimental(ExperimentalTypeInference::class) +fun build(@BuilderInference block: TestInterface.() -> Unit): R = TODO() + +@UseExperimental(ExperimentalTypeInference::class) +fun build2(@BuilderInference block: TestInterface.() -> Unit): R = TODO() + +class Inv + +interface TestInterface { + fun emit(r: R) + fun get(): R + fun getInv(): Inv +} + +fun id(x: U): U? = x +fun select(vararg x: E): E? = x[0] + +fun test() { + val ret = build { + emit("1") + Test.foo(get()) + ?")!>Test.foo(getInv()) + id(get()) + select(get(), get()) + select(Test.foo(get()), Test.foo(get())) + select(Test.foo(get()), get()) + ?")!>select(getInv(), getInv()) + ?")!>select(Test.foo(getInv()), Test.foo(getInv())) + ?")!>select(Test.foo(getInv()), getInv()) + ?")!>select(getInv(), Test.foo(getInv())) + select(id(get()), id(get())) + build2 { + emit(1) + select(this@build.get(), get()) + select(Test.foo(this@build.get()), Test.foo(get())) + ?")!>select(this@build.getInv(), getInv()) + ?")!>select(Test.foo(this@build.getInv()), Test.foo(getInv())) + ?")!>select(Test.foo(this@build.getInv()), getInv()) + select(id(this@build.get()), id(get())) + "" + } + "" + } + val ret2 = build { + emit("1") + select(get(), null) + select(Test.foo(null), Test.foo(get())) + select(Test.foo(get()), null) + ?")!>select(null, getInv()) + ?")!>select(Test.foo(getInv()), Test.foo(null)) + ?")!>select(Test.foo(null), getInv()) + ?")!>select(getInv(), Test.foo(null)) + select(id(null), id(get())) + build2 { + emit(1) + select(this@build.get(), get(), null) + select(Test.foo(this@build.get()), Test.foo(get()), null) + ?")!>select(this@build.getInv(), getInv(), null) + ?")!>select(Test.foo(this@build.getInv()), Test.foo(getInv()), null) + ?")!>select(Test.foo(this@build.getInv()), getInv(), null) + select(id(this@build.get()), id(get()), null) + "" + } + "" + } +} diff --git a/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperTypeNullable.txt b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperTypeNullable.txt new file mode 100644 index 00000000000..68ad8178487 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperTypeNullable.txt @@ -0,0 +1,33 @@ +package + +@kotlin.UseExperimental(markerClass = {kotlin.experimental.ExperimentalTypeInference::class}) public fun build(/*0*/ @kotlin.BuilderInference block: TestInterface.() -> kotlin.Unit): R +@kotlin.UseExperimental(markerClass = {kotlin.experimental.ExperimentalTypeInference::class}) public fun build2(/*0*/ @kotlin.BuilderInference block: TestInterface.() -> kotlin.Unit): R +public fun id(/*0*/ x: U): U? +public fun select(/*0*/ vararg x: E /*kotlin.Array*/): E? +public fun test(): kotlin.Unit + +public final class Inv { + public constructor Inv() + 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/*package*/ open class Test { + public/*package*/ constructor Test() + 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 + + // Static members + @org.jetbrains.annotations.Nullable public/*package*/ open fun foo(/*0*/ x: T!): T? +} + +public interface TestInterface { + public abstract fun emit(/*0*/ r: R): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract fun get(): R + public abstract fun getInv(): Inv + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/intersect.fir.kt b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/intersect.fir.kt new file mode 100644 index 00000000000..45544e47842 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/intersect.fir.kt @@ -0,0 +1,48 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER -UNCHECKED_CAST -DEPRECATION -EXPERIMENTAL_IS_NOT_ENABLED -UNUSED_VARIABLE +// WITH_RUNTIME + +// FILE: Test.java + +class Test { + static T foo(T x) { return x; } +} + +// FILE: main.kt +import kotlin.experimental.ExperimentalTypeInference + +@UseExperimental(ExperimentalTypeInference::class) +fun build(@BuilderInference block: TestInterface.() -> Unit): R1 = TODO() + +@UseExperimental(ExperimentalTypeInference::class) +fun build2(@BuilderInference block: TestInterface.() -> Unit): R2 = TODO() + +class In + +interface TestInterface { + fun emit(r: R) + fun get(): R + fun getIn(): In +} + +fun id(x: U) = x +fun intersect(vararg x: In): E = null as E + +fun test() { + val ret = build { + emit("1") + intersect(getIn(), getIn()) + intersect(getIn(), Test.foo(getIn())) + intersect(Test.foo(getIn()), Test.foo(getIn())) + intersect(Test.foo(getIn()), getIn()) + + build2 { + emit(1) + intersect(this@build.getIn(), getIn()) + intersect(getIn(), Test.foo(this@build.getIn())) + intersect(Test.foo(this@build.getIn()), Test.foo(getIn())) + intersect(Test.foo(getIn()), this@build.getIn()) + "" + } + "" + } +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/intersect.kt b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/intersect.kt new file mode 100644 index 00000000000..1177ced0883 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/intersect.kt @@ -0,0 +1,48 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER -UNCHECKED_CAST -DEPRECATION -EXPERIMENTAL_IS_NOT_ENABLED -UNUSED_VARIABLE +// WITH_RUNTIME + +// FILE: Test.java + +class Test { + static T foo(T x) { return x; } +} + +// FILE: main.kt +import kotlin.experimental.ExperimentalTypeInference + +@UseExperimental(ExperimentalTypeInference::class) +fun build(@BuilderInference block: TestInterface.() -> Unit): R1 = TODO() + +@UseExperimental(ExperimentalTypeInference::class) +fun build2(@BuilderInference block: TestInterface.() -> Unit): R2 = TODO() + +class In + +interface TestInterface { + fun emit(r: R) + fun get(): R + fun getIn(): In +} + +fun id(x: U) = x +fun intersect(vararg x: In): E = null as E + +fun test() { + val ret = build { + emit("1") + intersect(getIn(), getIn()) + intersect(getIn(), Test.foo(getIn())) + intersect(Test.foo(getIn()), Test.foo(getIn())) + intersect(Test.foo(getIn()), getIn()) + + build2 { + emit(1) + intersect(this@build.getIn(), getIn()) + intersect(getIn(), Test.foo(this@build.getIn())) + intersect(Test.foo(this@build.getIn()), Test.foo(getIn())) + intersect(Test.foo(getIn()), this@build.getIn()) + "" + } + "" + } +} diff --git a/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/intersect.txt b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/intersect.txt new file mode 100644 index 00000000000..947652f01d6 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/intersect.txt @@ -0,0 +1,33 @@ +package + +@kotlin.UseExperimental(markerClass = {kotlin.experimental.ExperimentalTypeInference::class}) public fun build(/*0*/ @kotlin.BuilderInference block: TestInterface.() -> kotlin.Unit): R1 +@kotlin.UseExperimental(markerClass = {kotlin.experimental.ExperimentalTypeInference::class}) public fun build2(/*0*/ @kotlin.BuilderInference block: TestInterface.() -> kotlin.Unit): R2 +public fun id(/*0*/ x: U): U +public fun intersect(/*0*/ vararg x: In /*kotlin.Array>*/): E +public fun test(): kotlin.Unit + +public final class In { + public constructor In() + 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/*package*/ open class Test { + public/*package*/ constructor Test() + 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 + + // Static members + public/*package*/ open fun foo(/*0*/ x: T!): T! +} + +public interface TestInterface { + public abstract fun emit(/*0*/ r: R): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public abstract fun get(): R + public abstract fun getIn(): In + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/tests/inference/builderInference/renderingStubTypes.fir.kt b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/renderingStubTypes.fir.kt similarity index 90% rename from compiler/testData/diagnostics/tests/inference/builderInference/renderingStubTypes.fir.kt rename to compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/renderingStubTypes.fir.kt index c05c459396b..5f7d1848552 100644 --- a/compiler/testData/diagnostics/tests/inference/builderInference/renderingStubTypes.fir.kt +++ b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/renderingStubTypes.fir.kt @@ -16,10 +16,13 @@ interface TestInterface { fun getInv(): Inv } +fun id(x: U) = x + fun test() { val ret = build { - emit(1) + emit("1") get() getInv() + "" } } diff --git a/compiler/testData/diagnostics/tests/inference/builderInference/renderingStubTypes.kt b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/renderingStubTypes.kt similarity index 100% rename from compiler/testData/diagnostics/tests/inference/builderInference/renderingStubTypes.kt rename to compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/renderingStubTypes.kt diff --git a/compiler/testData/diagnostics/tests/inference/builderInference/renderingStubTypes.txt b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/renderingStubTypes.txt similarity index 100% rename from compiler/testData/diagnostics/tests/inference/builderInference/renderingStubTypes.txt rename to compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/renderingStubTypes.txt diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/incorrectCalls.txt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/incorrectCalls.txt index a72fa6593da..aa1fb869364 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/incorrectCalls.txt +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/incorrectCalls.txt @@ -2,14 +2,8 @@ package public val test1: kotlin.collections.List public val test2: kotlin.collections.List -public val test3: [ERROR : Type for generate { - yield(3) - yieldBarReturnType(3) -}] -public val test4: [ERROR : Type for generate { - yield(3) - barReturnType() -}] +public val test3: kotlin.collections.List +public val test4: kotlin.collections.List public fun generate(/*0*/ @kotlin.BuilderInference g: suspend GenericController.() -> kotlin.Unit): kotlin.collections.List public final class GenericController { diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/inferCoroutineTypeInOldVersion.txt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/inferCoroutineTypeInOldVersion.txt index d490a4e90bf..efde51d672d 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/inferCoroutineTypeInOldVersion.txt +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/inferCoroutineTypeInOldVersion.txt @@ -1,8 +1,6 @@ package -public val extension: [ERROR : Type for build { - extensionAdd("foo") -}] +public val extension: kotlin.collections.List public val member: kotlin.collections.List public val memberWithoutAnn: [ERROR : Type for wrongBuild { add(42) diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/resolveUsualCallWithBuilderInference.txt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/resolveUsualCallWithBuilderInference.txt index 09f79370be6..4ba791ecafa 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/resolveUsualCallWithBuilderInference.txt +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/resolveUsualCallWithBuilderInference.txt @@ -1,8 +1,6 @@ package -public val extension: [ERROR : Type for build { - extensionAdd("foo") -}] +public val extension: kotlin.collections.List public val member: kotlin.collections.List public val memberWithoutAnn: [ERROR : Type for wrongBuild { add(42) diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/useInferenceInformationFromExtension.txt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/useInferenceInformationFromExtension.txt index bdb5071930e..9a2789c7e6e 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/useInferenceInformationFromExtension.txt +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/useInferenceInformationFromExtension.txt @@ -1,8 +1,6 @@ package -public val extension: [ERROR : Type for generate { - extensionYield("foo") -}] +public val extension: kotlin.collections.List public val normal: kotlin.collections.List public val safeExtension: kotlin.collections.List public fun generate(/*0*/ @kotlin.BuilderInference g: suspend GenericController.() -> kotlin.Unit): kotlin.collections.List diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/restrictSuspension/outerYield_1_3.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/restrictSuspension/outerYield_1_3.kt index a45e2cde834..01429bb45da 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/restrictSuspension/outerYield_1_3.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/restrictSuspension/outerYield_1_3.kt @@ -83,11 +83,11 @@ fun test() { this@a.yield2(1) with(this) { - yield("") - this@with.yield("") + yield("") + this@with.yield("") - yield2("") - this@with.yield2("") + yield2("") + this@with.yield2("") } } } diff --git a/compiler/testData/diagnostics/testsWithStdLib/inference/recursiveFlexibleAssertions.kt b/compiler/testData/diagnostics/testsWithStdLib/inference/recursiveFlexibleAssertions.kt index 95d690a2c86..889aae036e8 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/inference/recursiveFlexibleAssertions.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/inference/recursiveFlexibleAssertions.kt @@ -75,5 +75,5 @@ fun test() { } // TODO: FIR // {AbstractAssert<*, out Any!>! & EnumerableAssert<*, {Comparable<*> & java.io.Serializable!}>!} with unfolded flexible nullability - & EnumerableAssert<*, out ({Comparable<*> & java.io.Serializable}..{Comparable<*>? & java.io.Serializable?})>}..{AbstractAssert<*, out (kotlin.Any..kotlin.Any?)>? & EnumerableAssert<*, out ({Comparable<*> & java.io.Serializable}..{Comparable<*>? & java.io.Serializable?})>?})")!>assertion + & EnumerableAssert<*, out ({Comparable<*> & java.io.Serializable}..{Comparable<*>? & java.io.Serializable?})>}..{AbstractAssert<*, out (Any..Any?)>? & EnumerableAssert<*, out ({Comparable<*> & java.io.Serializable}..{Comparable<*>? & java.io.Serializable?})>?})")!>assertion } 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 2cad2413929..53d51b53061 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 @@ -12644,12 +12644,6 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/inference/builderInference"), Pattern.compile("^(.*)\\.kts?$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true); } - @Test - @TestMetadata("renderingStubTypes.kt") - public void testRenderingStubTypes() throws Exception { - runTest("compiler/testData/diagnostics/tests/inference/builderInference/renderingStubTypes.kt"); - } - @Test @TestMetadata("simpleLambdaInCallWithAnotherLambdaWithBuilderInference.kt") public void testSimpleLambdaInCallWithAnotherLambdaWithBuilderInference() throws Exception { @@ -12697,6 +12691,64 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { public void testSpecialCallsWithLambdas() throws Exception { runTest("compiler/testData/diagnostics/tests/inference/builderInference/specialCallsWithLambdas.kt"); } + + @Nested + @TestMetadata("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes") + @TestDataPath("$PROJECT_ROOT") + public class StubTypes { + @Test + public void testAllFilesPresentInStubTypes() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes"), Pattern.compile("^(.*)\\.kts?$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true); + } + + @Test + @TestMetadata("capturedTypes.kt") + public void testCapturedTypes() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/capturedTypes.kt"); + } + + @Test + @TestMetadata("commonSuperType.kt") + public void testCommonSuperType() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperType.kt"); + } + + @Test + @TestMetadata("commonSuperTypeContravariant.kt") + public void testCommonSuperTypeContravariant() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperTypeContravariant.kt"); + } + + @Test + @TestMetadata("commonSuperTypeCovariant.kt") + public void testCommonSuperTypeCovariant() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperTypeCovariant.kt"); + } + + @Test + @TestMetadata("commonSuperTypeInvariant.kt") + public void testCommonSuperTypeInvariant() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperTypeInvariant.kt"); + } + + @Test + @TestMetadata("commonSuperTypeNullable.kt") + public void testCommonSuperTypeNullable() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperTypeNullable.kt"); + } + + @Test + @TestMetadata("intersect.kt") + public void testIntersect() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/intersect.kt"); + } + + @Test + @TestMetadata("renderingStubTypes.kt") + public void testRenderingStubTypes() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/renderingStubTypes.kt"); + } + } } @Nested diff --git a/core/compiler.common/src/org/jetbrains/kotlin/types/AbstractTypeChecker.kt b/core/compiler.common/src/org/jetbrains/kotlin/types/AbstractTypeChecker.kt index 5b756a95c9d..fdebabe90b9 100644 --- a/core/compiler.common/src/org/jetbrains/kotlin/types/AbstractTypeChecker.kt +++ b/core/compiler.common/src/org/jetbrains/kotlin/types/AbstractTypeChecker.kt @@ -478,7 +478,11 @@ object AbstractTypeChecker { ) } - if (subType.isStubType() || superType.isStubType()) return context.isStubTypeEqualsToAnything + if (subType.isStubType() && superType.isStubType()) + return subType.typeConstructor() === superType.typeConstructor() + + if (subType.isStubType() || superType.isStubType() || subType.isStubTypeForVariableInSubtyping() || superType.isStubTypeForVariableInSubtyping()) + return context.isStubTypeEqualsToAnything // superType might be a definitely notNull type (see KT-42824) val superOriginalType = superType.asDefinitelyNotNullType()?.original() ?: superType @@ -742,7 +746,7 @@ object AbstractNullabilityChecker { if (type.isNothing()) return true if (type.isMarkedNullable()) return false - if (context.isStubTypeEqualsToAnything && type.isStubType()) return true + if (context.isStubTypeEqualsToAnything && (type.isStubTypeForVariableInSubtyping() || type.isStubType())) return true return areEqualTypeConstructors(type.typeConstructor(), end) } 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 7681aac48cb..9ec2df7c780 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 @@ -73,7 +73,7 @@ interface TypeSystemBuiltInsContext { /** * Context that allow construction of types */ -interface TypeSystemTypeFactoryContext { +interface TypeSystemTypeFactoryContext: TypeSystemBuiltInsContext { fun createFlexibleType(lowerBound: SimpleTypeMarker, upperBound: SimpleTypeMarker): KotlinTypeMarker fun createSimpleType( constructor: TypeConstructorMarker, @@ -169,7 +169,7 @@ interface TypeSystemInferenceExtensionContext : TypeSystemContext, TypeSystemBui ): CapturedTypeMarker fun createStubType(typeVariable: TypeVariableMarker): StubTypeMarker - + fun createStubTypeForTypeVariablesInSubtyping(typeVariable: TypeVariableMarker): StubTypeMarker fun KotlinTypeMarker.removeAnnotations(): KotlinTypeMarker fun KotlinTypeMarker.removeExactAnnotation(): KotlinTypeMarker @@ -299,6 +299,7 @@ interface TypeSystemContext : TypeSystemOptimizationContext { } fun SimpleTypeMarker.isStubType(): Boolean + fun SimpleTypeMarker.isStubTypeForVariableInSubtyping(): Boolean fun KotlinTypeMarker.asTypeArgument(): TypeArgumentMarker diff --git a/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRendererImpl.kt b/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRendererImpl.kt index f49ba9ed269..32ed0829084 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRendererImpl.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRendererImpl.kt @@ -288,7 +288,11 @@ internal class DescriptorRendererImpl( override fun renderTypeConstructor(typeConstructor: TypeConstructor): String = when (val cd = typeConstructor.declarationDescriptor) { is TypeParameterDescriptor, is ClassDescriptor, is TypeAliasDescriptor -> renderClassifierName(cd) - null -> typeConstructor.toString() + null -> { + if (typeConstructor is IntersectionTypeConstructor) { + typeConstructor.makeDebugNameForIntersectionType { if (it is StubType) it.originalTypeVariable else it } + } else typeConstructor.toString() + } else -> error("Unexpected classifier: " + cd::class.java) } diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/IntersectionTypeConstructor.kt b/core/descriptors/src/org/jetbrains/kotlin/types/IntersectionTypeConstructor.kt index 60f87d51b78..bc7d58c0fbe 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/IntersectionTypeConstructor.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/IntersectionTypeConstructor.kt @@ -61,11 +61,12 @@ class IntersectionTypeConstructor(typesToIntersect: Collection) : Ty override fun getBuiltIns(): KotlinBuiltIns = intersectedTypes.iterator().next().constructor.builtIns - override fun toString(): String = - makeDebugNameForIntersectionType(intersectedTypes) + override fun toString(): String = makeDebugNameForIntersectionType() - private fun makeDebugNameForIntersectionType(resultingTypes: Iterable): String = - resultingTypes.sortedBy { it.toString() }.joinToString(separator = " & ", prefix = "{", postfix = "}") + fun makeDebugNameForIntersectionType(getProperTypeRelatedToStringify: (KotlinType) -> Any = { it.toString() }): String { + return intersectedTypes.sortedBy { getProperTypeRelatedToStringify(it).toString() } + .joinToString(separator = " & ", prefix = "{", postfix = "}") { getProperTypeRelatedToStringify(it).toString() } + } override fun equals(other: Any?): Boolean { if (this === other) return true diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/StubType.kt b/core/descriptors/src/org/jetbrains/kotlin/types/StubType.kt index 266a0a16fd3..1f9abad468b 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/StubType.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/StubType.kt @@ -23,6 +23,17 @@ class StubType( } } +class StubTypeForTypeVariablesInSubtyping( + originalTypeVariable: TypeConstructor, + isMarkedNullable: Boolean, + constructor: TypeConstructor = ErrorUtils.createErrorTypeConstructor("Constructor for non fixed type: $originalTypeVariable"), + memberScope: MemberScope = ErrorUtils.createErrorScope("Scope for non fixed type: $originalTypeVariable") +) : AbstractStubType(originalTypeVariable, isMarkedNullable, constructor, memberScope), StubTypeMarker { + override fun materialize(newNullability: Boolean): AbstractStubType { + return StubTypeForTypeVariablesInSubtyping(originalTypeVariable, newNullability, constructor, memberScope) + } +} + // This type is used as a replacement of type variables for provideDelegate resolve class StubTypeForProvideDelegateReceiver( originalTypeVariable: TypeConstructor, @@ -54,7 +65,7 @@ abstract class AbstractStubType( } override fun toString(): String { - return "NonFixed: $originalTypeVariable" + return "NonFixed: $originalTypeVariable${if (isMarkedNullable) "?" else ""}" } @TypeRefinement 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 1b5330b0a46..052fb12c557 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/checker/ClassicTypeSystemContext.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/checker/ClassicTypeSystemContext.kt @@ -81,7 +81,12 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSy override fun SimpleTypeMarker.isStubType(): Boolean { require(this is SimpleType, this::errorMessage) - return this is AbstractStubType + return this is StubType || this is StubTypeForProvideDelegateReceiver + } + + override fun SimpleTypeMarker.isStubTypeForVariableInSubtyping(): Boolean { + require(this is SimpleType, this::errorMessage) + return this is StubTypeForTypeVariablesInSubtyping } override fun CapturedTypeMarker.lowerType(): KotlinTypeMarker? { @@ -543,6 +548,10 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSy errorSupportedOnlyInTypeInference() } + override fun createStubTypeForTypeVariablesInSubtyping(typeVariable: TypeVariableMarker): StubTypeMarker { + errorSupportedOnlyInTypeInference() + } + override fun KotlinTypeMarker.isSpecial(): Boolean { require(this is KotlinType) return this is TypeUtils.SpecialType diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/flexibleTypes.kt b/core/descriptors/src/org/jetbrains/kotlin/types/flexibleTypes.kt index 31deca759d2..deeb9e9bb3d 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/flexibleTypes.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/flexibleTypes.kt @@ -136,6 +136,8 @@ class FlexibleTypeImpl(lowerBound: SimpleType, upperBound: SimpleType) : Flexibl return renderer.renderFlexibleType(renderer.renderType(lowerBound), renderer.renderType(upperBound), builtIns) } + override fun toString() = "($lowerBound..$upperBound)" + override fun makeNullableAsSpecified(newNullability: Boolean): UnwrappedType = KotlinTypeFactory.flexibleType( lowerBound.makeNullableAsSpecified(newNullability), upperBound.makeNullableAsSpecified(newNullability)