diff --git a/compiler/backend-common/src/org/jetbrains/kotlin/backend/common/SamType.kt b/compiler/backend-common/src/org/jetbrains/kotlin/backend/common/SamType.kt index b2706480eec..67edfb64cf7 100644 --- a/compiler/backend-common/src/org/jetbrains/kotlin/backend/common/SamType.kt +++ b/compiler/backend-common/src/org/jetbrains/kotlin/backend/common/SamType.kt @@ -6,14 +6,17 @@ package org.jetbrains.kotlin.backend.common import org.jetbrains.kotlin.builtins.KotlinBuiltIns +import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor import org.jetbrains.kotlin.resolve.sam.getAbstractMembers import org.jetbrains.kotlin.types.* +import org.jetbrains.kotlin.types.checker.intersectWrappedTypes +import org.jetbrains.kotlin.types.typeUtil.builtIns import org.jetbrains.kotlin.types.typeUtil.replaceArgumentsWithNothing -class SamType constructor(val type: KotlinType) { +class SamType constructor(val type: KotlinType, val hasUnapproximatableArguments: Boolean = false) { val classDescriptor: ClassDescriptor get() = type.constructor.declarationDescriptor as? ClassDescriptor ?: error("Sam/Fun interface not a class descriptor: $type") @@ -38,7 +41,9 @@ class SamType constructor(val type: KotlinType) { } open class SamTypeFactory { - fun createByValueParameter(valueParameter: ValueParameterDescriptor): SamType? { + private lateinit var typeApproximator: TypeApproximator + + fun createByValueParameter(valueParameter: ValueParameterDescriptor, languageVersionSettings: LanguageVersionSettings): SamType? { val singleArgumentType: KotlinType val originalSingleArgumentType: KotlinType? val varargElementType = valueParameter.varargElementType @@ -56,6 +61,11 @@ open class SamTypeFactory { if (singleArgumentType.isError || originalSingleArgumentType!!.isError) { return null } + + if (!::typeApproximator.isInitialized) { + typeApproximator = TypeApproximator(singleArgumentType.builtIns, languageVersionSettings) + } + // This can be true in case when the value parameter is in the method of a generic type with out-projection. // We approximate Inv to Nothing, while Inv itself can be a SAM interface safe to call here // (see testData genericSamProjectedOut.kt for details) @@ -63,20 +73,41 @@ open class SamTypeFactory { // so we use Nothing arguments instead that leads to a raw type used for a SAM wrapper. // See org.jetbrains.kotlin.codegen.state.KotlinTypeMapper#writeGenericType to understand how // raw types and Nothing arguments relate. - val originalTypeToUse = - if (KotlinBuiltIns.isNothing(singleArgumentType)) - originalSingleArgumentType.replaceArgumentsWithNothing() - else singleArgumentType - return create(originalTypeToUse.removeExternalProjections()) + val originalTypeToUse = if (KotlinBuiltIns.isNothing(singleArgumentType)) + originalSingleArgumentType.replaceArgumentsWithNothing() + else singleArgumentType + val approximatedOriginalTypeToUse = typeApproximator.approximateToSubType( + originalTypeToUse, + TypeApproximatorConfiguration.UpperBoundAwareIntersectionTypeApproximator + ) ?: originalTypeToUse + approximatedOriginalTypeToUse as KotlinType + val hasUnapproximatableArguments = hasUnapproximatableArguments(approximatedOriginalTypeToUse) + + return create((approximatedOriginalTypeToUse).removeExternalProjections(), hasUnapproximatableArguments) } + /* + * declaration site: `class Foo where T: X, T: Y {}`, X and Y aren't related by subtyping + * use site: Foo + * => `in {X & Y}` is unapproximatable type argument + */ + fun hasUnapproximatableArguments(type: KotlinType) = + type.arguments.isNotEmpty() && type.arguments.withIndex().any { (i, argument) -> + if (argument.projectionKind != Variance.IN_VARIANCE) return@any false + if (argument.type.constructor !is IntersectionTypeConstructor) return@any false + val typeParameter = type.constructor.parameters.getOrNull(i) ?: return@any false + // we have really intersection type as the result => at least there are two upper bounds which aren't related by subtyping + intersectWrappedTypes(typeParameter.upperBounds).constructor is IntersectionTypeConstructor + } + open fun isSamType(type: KotlinType): Boolean { val descriptor = type.constructor.declarationDescriptor return descriptor is ClassDescriptor && descriptor.isFun } - fun create(originalType: KotlinType): SamType? { - return if (isSamType(originalType)) SamType(originalType) else null + @JvmOverloads + fun create(originalType: KotlinType, hasUnapproximatableArguments: Boolean = false): SamType? { + return if (isSamType(originalType)) SamType(originalType, hasUnapproximatableArguments) else null } private fun KotlinType.removeExternalProjections(): KotlinType { diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/CodegenAnnotatingVisitor.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/CodegenAnnotatingVisitor.java index 8f775083387..092867ccf31 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/CodegenAnnotatingVisitor.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/binding/CodegenAnnotatingVisitor.java @@ -862,7 +862,7 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid { if (valueArguments == null) return; for (ValueParameterDescriptor valueParameter : valueParametersWithSAMConversion) { - SamType samType = JvmSamTypeFactory.INSTANCE.createByValueParameter(valueParameter); + SamType samType = JvmSamTypeFactory.INSTANCE.createByValueParameter(valueParameter, this.languageVersionSettings); if (samType == null) continue; ResolvedValueArgument resolvedValueArgument = valueArguments.get(valueParameter.getIndex()); @@ -874,7 +874,7 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid { } private void recordSamTypeOnArgumentExpression(ValueParameterDescriptor valueParameter, ValueArgument valueArgument) { - SamType samType = JvmSamTypeFactory.INSTANCE.createByValueParameter(valueParameter); + SamType samType = JvmSamTypeFactory.INSTANCE.createByValueParameter(valueParameter, this.languageVersionSettings); if (samType == null) return; recordSamTypeOnArgumentExpression(samType, valueArgument); @@ -973,7 +973,7 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid { FunctionDescriptor original = SamCodegenUtil.getOriginalIfSamAdapter((FunctionDescriptor) operationDescriptor); if (original == null) return; - SamType samType = JvmSamTypeFactory.INSTANCE.createByValueParameter(original.getValueParameters().get(0)); + SamType samType = JvmSamTypeFactory.INSTANCE.createByValueParameter(original.getValueParameters().get(0), this.languageVersionSettings); if (samType == null) return; IElementType token = expression.getOperationToken(); @@ -1002,7 +1002,7 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid { List indexExpressions = expression.getIndexExpressions(); List parameters = original.getValueParameters(); for (ValueParameterDescriptor valueParameter : parameters) { - SamType samType = JvmSamTypeFactory.INSTANCE.createByValueParameter(valueParameter); + SamType samType = JvmSamTypeFactory.INSTANCE.createByValueParameter(valueParameter, this.languageVersionSettings); if (samType == null) continue; if (isSetter && valueParameter.getIndex() == parameters.size() - 1) { diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java index 511d835fe90..e02853b9923 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java @@ -39182,6 +39182,40 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT } } + @Nested + @TestMetadata("compiler/testData/codegen/box/sam/approximation") + @TestDataPath("$PROJECT_ROOT") + public class Approximation { + @Test + public void testAllFilesPresentInApproximation() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/sam/approximation"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); + } + + @Test + @TestMetadata("approxToIntermediateType.kt") + public void testApproxToIntermediateType() throws Exception { + runTest("compiler/testData/codegen/box/sam/approximation/approxToIntermediateType.kt"); + } + + @Test + @TestMetadata("approxToSingleUpperBound.kt") + public void testApproxToSingleUpperBound() throws Exception { + runTest("compiler/testData/codegen/box/sam/approximation/approxToSingleUpperBound.kt"); + } + + @Test + @TestMetadata("impossibleToApproxToRepresentable.kt") + public void testImpossibleToApproxToRepresentable() throws Exception { + runTest("compiler/testData/codegen/box/sam/approximation/impossibleToApproxToRepresentable.kt"); + } + + @Test + @TestMetadata("impossibleToApproxToRepresentable2.kt") + public void testImpossibleToApproxToRepresentable2() throws Exception { + runTest("compiler/testData/codegen/box/sam/approximation/impossibleToApproxToRepresentable2.kt"); + } + } + @Nested @TestMetadata("compiler/testData/codegen/box/sam/constructors") @TestDataPath("$PROJECT_ROOT") 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 66d48256b72..eabb5313aef 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 @@ -284,6 +284,11 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty return this.symbol.fir.bounds[index].coneType } + override fun TypeParameterMarker.getUpperBounds(): List { + require(this is ConeTypeParameterLookupTag) + return this.symbol.fir.bounds.map { it.coneType } + } + override fun TypeParameterMarker.getTypeConstructor(): TypeConstructorMarker { require(this is ConeTypeParameterLookupTag) return this diff --git a/compiler/ir/backend.jvm/entrypoint/src/org/jetbrains/kotlin/backend/jvm/JvmGeneratorExtensionsImpl.kt b/compiler/ir/backend.jvm/entrypoint/src/org/jetbrains/kotlin/backend/jvm/JvmGeneratorExtensionsImpl.kt index 13fe1172e0e..eab98001e4d 100644 --- a/compiler/ir/backend.jvm/entrypoint/src/org/jetbrains/kotlin/backend/jvm/JvmGeneratorExtensionsImpl.kt +++ b/compiler/ir/backend.jvm/entrypoint/src/org/jetbrains/kotlin/backend/jvm/JvmGeneratorExtensionsImpl.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.backend.jvm import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclarationWithWrappedDescriptor import org.jetbrains.kotlin.backend.common.ir.createParameterDeclarations import org.jetbrains.kotlin.codegen.JvmSamTypeFactory +import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.annotations.FilteredAnnotations import org.jetbrains.kotlin.incremental.components.NoLookupLocation @@ -59,8 +60,10 @@ open class JvmGeneratorExtensionsImpl(private val generateFacades: Boolean = tru override fun isPlatformSamType(type: KotlinType): Boolean = JavaSingleAbstractMethodUtils.isSamType(type) - override fun getSamTypeForValueParameter(valueParameter: ValueParameterDescriptor): KotlinType? = - JvmSamTypeFactory.createByValueParameter(valueParameter)?.type + override fun getSamTypeForValueParameter( + valueParameter: ValueParameterDescriptor, + languageVersionSettings: LanguageVersionSettings + ): KotlinType? = JvmSamTypeFactory.createByValueParameter(valueParameter, languageVersionSettings)?.type companion object Instance : JvmSamConversion() } diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ArgumentsGenerationUtils.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ArgumentsGenerationUtils.kt index 536e307f17e..6fd225ea3de 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ArgumentsGenerationUtils.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ArgumentsGenerationUtils.kt @@ -585,7 +585,7 @@ fun StatementGenerator.generateSamConversionForValueArgumentsIfRequired(call: Ca if (!originalValueParameters[i].type.isFunctionTypeOrSubtype) continue } - val samKotlinType = samConversion.getSamTypeForValueParameter(underlyingValueParameter) + val samKotlinType = samConversion.getSamTypeForValueParameter(underlyingValueParameter, context.languageVersionSettings) ?: underlyingValueParameter.varargElementType // If we have a vararg, vararg element type will be taken ?: underlyingValueParameter.type diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/GeneratorExtensions.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/GeneratorExtensions.kt index a86626cc573..bc97737549b 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/GeneratorExtensions.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/GeneratorExtensions.kt @@ -16,6 +16,7 @@ import org.jetbrains.kotlin.psi.KtPureClassOrObject import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.backend.common.SamTypeFactory +import org.jetbrains.kotlin.config.LanguageVersionSettings open class GeneratorExtensions : StubGeneratorExtensions() { open val samConversion: SamConversion @@ -24,8 +25,10 @@ open class GeneratorExtensions : StubGeneratorExtensions() { open class SamConversion { open fun isPlatformSamType(type: KotlinType): Boolean = false - open fun getSamTypeForValueParameter(valueParameter: ValueParameterDescriptor): KotlinType? = - SamTypeFactory.INSTANCE.createByValueParameter(valueParameter)?.type + open fun getSamTypeForValueParameter( + valueParameter: ValueParameterDescriptor, + languageVersionSettings: LanguageVersionSettings + ): KotlinType? = SamTypeFactory.INSTANCE.createByValueParameter(valueParameter, languageVersionSettings)?.type companion object Instance : SamConversion() } 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 830f1f12757..db23bacbdca 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 @@ -176,6 +176,8 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon override fun TypeParameterMarker.getUpperBound(index: Int) = getSuperTypes(this)[index] as KotlinTypeMarker + override fun TypeParameterMarker.getUpperBounds() = getSuperTypes(this) as List + override fun TypeParameterMarker.getTypeConstructor() = this as IrTypeParameterSymbol private fun KotlinTypeMarker.containsTypeConstructor(constructor: TypeConstructorMarker): Boolean { diff --git a/compiler/testData/codegen/box/sam/approximation/approxToIntermediateType.kt b/compiler/testData/codegen/box/sam/approximation/approxToIntermediateType.kt new file mode 100644 index 00000000000..0aa54603468 --- /dev/null +++ b/compiler/testData/codegen/box/sam/approximation/approxToIntermediateType.kt @@ -0,0 +1,23 @@ +interface X +interface Z + +interface W : X, Z + +interface A : W +interface B : W + +fun interface IFoo where T : X, T : Z { + fun accept(t: T) +} + +fun sel(x: T, y: T) = x + +class G where T: X, T: Z { + fun check(x: IFoo) {} +} + +fun box(): String { + val g = sel(G(), G()) // g: G + g.check {} // target SAM type: IFoo + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/sam/approximation/approxToSingleUpperBound.kt b/compiler/testData/codegen/box/sam/approximation/approxToSingleUpperBound.kt new file mode 100644 index 00000000000..a298c4d7714 --- /dev/null +++ b/compiler/testData/codegen/box/sam/approximation/approxToSingleUpperBound.kt @@ -0,0 +1,21 @@ +interface X +interface Z + +interface A : X, Z +interface B : X, Z + +fun interface IFoo { + fun accept(t: T) +} + +fun sel(x: T, y: T) = x + +class G { + fun check(x: IFoo) {} +} + +fun box(): String { + val g = sel(G(), G()) // g: G + g.check {} // (*) target SAM type: IFoo + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/sam/approximation/impossibleToApproxToRepresentable.kt b/compiler/testData/codegen/box/sam/approximation/impossibleToApproxToRepresentable.kt new file mode 100644 index 00000000000..e23d0f2ad9b --- /dev/null +++ b/compiler/testData/codegen/box/sam/approximation/impossibleToApproxToRepresentable.kt @@ -0,0 +1,21 @@ +interface X +interface Z + +interface A : X, Z +interface B : X, Z + +fun interface IFoo where T : X, T : Z { + fun accept(t: T) +} + +fun sel(x: T, y: T) = x + +class G where T: X, T: Z { + fun check(x: IFoo) {} +} + +fun box(): String { + val g = sel(G(), G()) // g: G + g.check {} // (*) target SAM type: IFoo<{ X & Z }> (TODO: report a compile time error for this case) + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/sam/approximation/impossibleToApproxToRepresentable2.kt b/compiler/testData/codegen/box/sam/approximation/impossibleToApproxToRepresentable2.kt new file mode 100644 index 00000000000..c55ad4f3100 --- /dev/null +++ b/compiler/testData/codegen/box/sam/approximation/impossibleToApproxToRepresentable2.kt @@ -0,0 +1,24 @@ +interface X: U, W +interface Z: U, W + +interface U +interface W + +interface A : X, Z +interface B : X, Z + +fun interface IFoo where T : U, T : W { + fun accept(t: T) +} + +fun sel(x: T, y: T) = x + +class G where T: U, T: W { + fun check(x: IFoo) {} +} + +fun box(): String { + val g = sel(G(), G()) + g.check {} // TODO: report a compile time error for this case + return "OK" +} \ No newline at end of file diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java index c8dc80ab802..39988fa095a 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java @@ -39140,6 +39140,40 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { } } + @Nested + @TestMetadata("compiler/testData/codegen/box/sam/approximation") + @TestDataPath("$PROJECT_ROOT") + public class Approximation { + @Test + public void testAllFilesPresentInApproximation() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/sam/approximation"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true); + } + + @Test + @TestMetadata("approxToIntermediateType.kt") + public void testApproxToIntermediateType() throws Exception { + runTest("compiler/testData/codegen/box/sam/approximation/approxToIntermediateType.kt"); + } + + @Test + @TestMetadata("approxToSingleUpperBound.kt") + public void testApproxToSingleUpperBound() throws Exception { + runTest("compiler/testData/codegen/box/sam/approximation/approxToSingleUpperBound.kt"); + } + + @Test + @TestMetadata("impossibleToApproxToRepresentable.kt") + public void testImpossibleToApproxToRepresentable() throws Exception { + runTest("compiler/testData/codegen/box/sam/approximation/impossibleToApproxToRepresentable.kt"); + } + + @Test + @TestMetadata("impossibleToApproxToRepresentable2.kt") + public void testImpossibleToApproxToRepresentable2() throws Exception { + runTest("compiler/testData/codegen/box/sam/approximation/impossibleToApproxToRepresentable2.kt"); + } + } + @Nested @TestMetadata("compiler/testData/codegen/box/sam/constructors") @TestDataPath("$PROJECT_ROOT") diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java index 46ae4f3347f..8076f0e6ecf 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java @@ -39182,6 +39182,40 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes } } + @Nested + @TestMetadata("compiler/testData/codegen/box/sam/approximation") + @TestDataPath("$PROJECT_ROOT") + public class Approximation { + @Test + public void testAllFilesPresentInApproximation() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/sam/approximation"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); + } + + @Test + @TestMetadata("approxToIntermediateType.kt") + public void testApproxToIntermediateType() throws Exception { + runTest("compiler/testData/codegen/box/sam/approximation/approxToIntermediateType.kt"); + } + + @Test + @TestMetadata("approxToSingleUpperBound.kt") + public void testApproxToSingleUpperBound() throws Exception { + runTest("compiler/testData/codegen/box/sam/approximation/approxToSingleUpperBound.kt"); + } + + @Test + @TestMetadata("impossibleToApproxToRepresentable.kt") + public void testImpossibleToApproxToRepresentable() throws Exception { + runTest("compiler/testData/codegen/box/sam/approximation/impossibleToApproxToRepresentable.kt"); + } + + @Test + @TestMetadata("impossibleToApproxToRepresentable2.kt") + public void testImpossibleToApproxToRepresentable2() throws Exception { + runTest("compiler/testData/codegen/box/sam/approximation/impossibleToApproxToRepresentable2.kt"); + } + } + @Nested @TestMetadata("compiler/testData/codegen/box/sam/constructors") @TestDataPath("$PROJECT_ROOT") diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 56585167a0b..8f91bbd0036 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -31285,6 +31285,39 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes } } + @TestMetadata("compiler/testData/codegen/box/sam/approximation") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Approximation extends AbstractLightAnalysisModeTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath); + } + + public void testAllFilesPresentInApproximation() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/sam/approximation"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true); + } + + @TestMetadata("approxToIntermediateType.kt") + public void testApproxToIntermediateType() throws Exception { + runTest("compiler/testData/codegen/box/sam/approximation/approxToIntermediateType.kt"); + } + + @TestMetadata("approxToSingleUpperBound.kt") + public void testApproxToSingleUpperBound() throws Exception { + runTest("compiler/testData/codegen/box/sam/approximation/approxToSingleUpperBound.kt"); + } + + @TestMetadata("impossibleToApproxToRepresentable.kt") + public void testImpossibleToApproxToRepresentable() throws Exception { + runTest("compiler/testData/codegen/box/sam/approximation/impossibleToApproxToRepresentable.kt"); + } + + @TestMetadata("impossibleToApproxToRepresentable2.kt") + public void testImpossibleToApproxToRepresentable2() throws Exception { + runTest("compiler/testData/codegen/box/sam/approximation/impossibleToApproxToRepresentable2.kt"); + } + } + @TestMetadata("compiler/testData/codegen/box/sam/constructors") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) 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 b2f87ed5c23..cffae338c38 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 @@ -325,6 +325,7 @@ interface TypeSystemContext : TypeSystemOptimizationContext { fun TypeParameterMarker.getVariance(): TypeVariance fun TypeParameterMarker.upperBoundCount(): Int fun TypeParameterMarker.getUpperBound(index: Int): KotlinTypeMarker + fun TypeParameterMarker.getUpperBounds(): List fun TypeParameterMarker.getTypeConstructor(): TypeConstructorMarker fun TypeParameterMarker.hasRecursiveBounds(selfConstructor: TypeConstructorMarker): Boolean 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 80f46692f86..f9518e9353f 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/checker/ClassicTypeSystemContext.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/checker/ClassicTypeSystemContext.kt @@ -230,6 +230,11 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSy return this.upperBounds[index] } + override fun TypeParameterMarker.getUpperBounds(): List { + require(this is TypeParameterDescriptor, this::errorMessage) + return this.upperBounds + } + override fun TypeParameterMarker.getTypeConstructor(): TypeConstructorMarker { require(this is TypeParameterDescriptor, this::errorMessage) return this.typeConstructor diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java index bd1fea93dba..bda657f841e 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java @@ -26285,6 +26285,39 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes } } + @TestMetadata("compiler/testData/codegen/box/sam/approximation") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Approximation extends AbstractIrJsCodegenBoxES6Test { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR_ES6, testDataFilePath); + } + + public void testAllFilesPresentInApproximation() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/sam/approximation"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR_ES6, true); + } + + @TestMetadata("approxToIntermediateType.kt") + public void testApproxToIntermediateType() throws Exception { + runTest("compiler/testData/codegen/box/sam/approximation/approxToIntermediateType.kt"); + } + + @TestMetadata("approxToSingleUpperBound.kt") + public void testApproxToSingleUpperBound() throws Exception { + runTest("compiler/testData/codegen/box/sam/approximation/approxToSingleUpperBound.kt"); + } + + @TestMetadata("impossibleToApproxToRepresentable.kt") + public void testImpossibleToApproxToRepresentable() throws Exception { + runTest("compiler/testData/codegen/box/sam/approximation/impossibleToApproxToRepresentable.kt"); + } + + @TestMetadata("impossibleToApproxToRepresentable2.kt") + public void testImpossibleToApproxToRepresentable2() throws Exception { + runTest("compiler/testData/codegen/box/sam/approximation/impossibleToApproxToRepresentable2.kt"); + } + } + @TestMetadata("compiler/testData/codegen/box/sam/constructors") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java index 91244aecc94..47016356f74 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java @@ -25691,6 +25691,39 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { } } + @TestMetadata("compiler/testData/codegen/box/sam/approximation") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Approximation extends AbstractIrJsCodegenBoxTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR, testDataFilePath); + } + + public void testAllFilesPresentInApproximation() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/sam/approximation"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true); + } + + @TestMetadata("approxToIntermediateType.kt") + public void testApproxToIntermediateType() throws Exception { + runTest("compiler/testData/codegen/box/sam/approximation/approxToIntermediateType.kt"); + } + + @TestMetadata("approxToSingleUpperBound.kt") + public void testApproxToSingleUpperBound() throws Exception { + runTest("compiler/testData/codegen/box/sam/approximation/approxToSingleUpperBound.kt"); + } + + @TestMetadata("impossibleToApproxToRepresentable.kt") + public void testImpossibleToApproxToRepresentable() throws Exception { + runTest("compiler/testData/codegen/box/sam/approximation/impossibleToApproxToRepresentable.kt"); + } + + @TestMetadata("impossibleToApproxToRepresentable2.kt") + public void testImpossibleToApproxToRepresentable2() throws Exception { + runTest("compiler/testData/codegen/box/sam/approximation/impossibleToApproxToRepresentable2.kt"); + } + } + @TestMetadata("compiler/testData/codegen/box/sam/constructors") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index 1f164476833..8f191cd0c02 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -25651,6 +25651,39 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { } } + @TestMetadata("compiler/testData/codegen/box/sam/approximation") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Approximation extends AbstractJsCodegenBoxTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath); + } + + public void testAllFilesPresentInApproximation() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/sam/approximation"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true); + } + + @TestMetadata("approxToIntermediateType.kt") + public void testApproxToIntermediateType() throws Exception { + runTest("compiler/testData/codegen/box/sam/approximation/approxToIntermediateType.kt"); + } + + @TestMetadata("approxToSingleUpperBound.kt") + public void testApproxToSingleUpperBound() throws Exception { + runTest("compiler/testData/codegen/box/sam/approximation/approxToSingleUpperBound.kt"); + } + + @TestMetadata("impossibleToApproxToRepresentable.kt") + public void testImpossibleToApproxToRepresentable() throws Exception { + runTest("compiler/testData/codegen/box/sam/approximation/impossibleToApproxToRepresentable.kt"); + } + + @TestMetadata("impossibleToApproxToRepresentable2.kt") + public void testImpossibleToApproxToRepresentable2() throws Exception { + runTest("compiler/testData/codegen/box/sam/approximation/impossibleToApproxToRepresentable2.kt"); + } + } + @TestMetadata("compiler/testData/codegen/box/sam/constructors") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java index 5d375a8c969..25571187297 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java @@ -14022,6 +14022,39 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest } } + @TestMetadata("compiler/testData/codegen/box/sam/approximation") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Approximation extends AbstractIrCodegenBoxWasmTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest0(this::doTest, TargetBackend.WASM, testDataFilePath); + } + + public void testAllFilesPresentInApproximation() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/sam/approximation"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.WASM, true); + } + + @TestMetadata("approxToIntermediateType.kt") + public void testApproxToIntermediateType() throws Exception { + runTest("compiler/testData/codegen/box/sam/approximation/approxToIntermediateType.kt"); + } + + @TestMetadata("approxToSingleUpperBound.kt") + public void testApproxToSingleUpperBound() throws Exception { + runTest("compiler/testData/codegen/box/sam/approximation/approxToSingleUpperBound.kt"); + } + + @TestMetadata("impossibleToApproxToRepresentable.kt") + public void testImpossibleToApproxToRepresentable() throws Exception { + runTest("compiler/testData/codegen/box/sam/approximation/impossibleToApproxToRepresentable.kt"); + } + + @TestMetadata("impossibleToApproxToRepresentable2.kt") + public void testImpossibleToApproxToRepresentable2() throws Exception { + runTest("compiler/testData/codegen/box/sam/approximation/impossibleToApproxToRepresentable2.kt"); + } + } + @TestMetadata("compiler/testData/codegen/box/sam/constructors") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class)