From 30a5eee48133d46669a97587e8e4f9e5e0b8c2d0 Mon Sep 17 00:00:00 2001 From: Victor Petukhov Date: Tue, 29 Dec 2020 14:21:08 +0300 Subject: [PATCH] Don't approximate abbreviation during substitution it as it can't be projected at top-level ^KT-42036 Fixed --- ...irOldFrontendDiagnosticsTestGenerated.java | 6 ++ .../ir/FirBlackBoxCodegenTestGenerated.java | 5 + ...pturedTypesSubstitutionIntoAbbreviation.kt | 32 +++++++ ...edTypesSubstitutionIntoAbbreviation.fir.kt | 31 +++++++ ...pturedTypesSubstitutionIntoAbbreviation.kt | 31 +++++++ ...turedTypesSubstitutionIntoAbbreviation.txt | 93 +++++++++++++++++++ .../test/runners/DiagnosticTestGenerated.java | 6 ++ .../codegen/BlackBoxCodegenTestGenerated.java | 5 + .../LightAnalysisModeTestGenerated.java | 5 + .../ir/IrBlackBoxCodegenTestGenerated.java | 5 + .../inference/CapturedTypeConstructor.kt | 2 +- .../kotlin/types/TypeSubstitution.kt | 4 +- .../kotlin/types/TypeSubstitutor.java | 17 +++- .../IrJsCodegenBoxES6TestGenerated.java | 5 + .../IrJsCodegenBoxTestGenerated.java | 5 + .../semantics/JsCodegenBoxTestGenerated.java | 5 + .../IrCodegenBoxWasmTestGenerated.java | 5 + 17 files changed, 258 insertions(+), 4 deletions(-) create mode 100644 compiler/testData/codegen/box/inference/capturedTypesSubstitutionIntoAbbreviation.kt create mode 100644 compiler/testData/diagnostics/tests/inference/capturedTypes/capturedTypesSubstitutionIntoAbbreviation.fir.kt create mode 100644 compiler/testData/diagnostics/tests/inference/capturedTypes/capturedTypesSubstitutionIntoAbbreviation.kt create mode 100644 compiler/testData/diagnostics/tests/inference/capturedTypes/capturedTypesSubstitutionIntoAbbreviation.txt 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 6a8aa712660..c8f92fa41b9 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 @@ -12426,6 +12426,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti runTest("compiler/testData/diagnostics/tests/inference/capturedTypes/capturedTypeWithTypeVariableSubtyping.kt"); } + @Test + @TestMetadata("capturedTypesSubstitutionIntoAbbreviation.kt") + public void testCapturedTypesSubstitutionIntoAbbreviation() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/capturedTypes/capturedTypesSubstitutionIntoAbbreviation.kt"); + } + @Test @TestMetadata("capturingFromArgumentOfFlexibleType.kt") public void testCapturingFromArgumentOfFlexibleType() throws Exception { diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java index 575fd44d2c8..ec7f7882421 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java @@ -13301,6 +13301,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/inference/capturedStarProjection.kt"); } + @TestMetadata("capturedTypesSubstitutionIntoAbbreviation.kt") + public void testCapturedTypesSubstitutionIntoAbbreviation() throws Exception { + runTest("compiler/testData/codegen/box/inference/capturedTypesSubstitutionIntoAbbreviation.kt"); + } + @TestMetadata("coercionToUnitForLambdaReturnTypeWithFlexibleConstraint.kt") public void testCoercionToUnitForLambdaReturnTypeWithFlexibleConstraint() throws Exception { runTest("compiler/testData/codegen/box/inference/coercionToUnitForLambdaReturnTypeWithFlexibleConstraint.kt"); diff --git a/compiler/testData/codegen/box/inference/capturedTypesSubstitutionIntoAbbreviation.kt b/compiler/testData/codegen/box/inference/capturedTypesSubstitutionIntoAbbreviation.kt new file mode 100644 index 00000000000..806140fd345 --- /dev/null +++ b/compiler/testData/codegen/box/inference/capturedTypesSubstitutionIntoAbbreviation.kt @@ -0,0 +1,32 @@ +typealias Action = (@UnsafeVariance K) -> Unit +typealias Action2 = (@UnsafeVariance K) -> K + +data class Tag(val action: Action) +data class Tag2(val action: Action) +data class Tag3(val action: Action) +data class Tag4(val action: Action) +data class Tag5(val action: Action2) +data class Tag6(val action: Action) +data class Tag7(val action: Action) +data class Tag8(val action: Action2) + +fun getTag(): Tag<*> = Tag {} +fun getTag2(): Tag2<*> = Tag2 {} +fun getTag3(): Tag3<*> = Tag3 {} +fun getTag4(): Tag4<*> = Tag4 {} +fun getTag5(): Tag5<*> = Tag5 { 1 } +fun getTag6(): Tag6<*> = Tag6 { } +fun getTag7(): Tag7<*> = Tag7 { } +fun getTag8(): Tag8<*> = Tag8 { 1 } + +fun box(): String { + getTag().action + getTag2().action + getTag3().action + getTag4().action + getTag5().action + getTag6().action + getTag7().action + getTag8().action + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/inference/capturedTypes/capturedTypesSubstitutionIntoAbbreviation.fir.kt b/compiler/testData/diagnostics/tests/inference/capturedTypes/capturedTypesSubstitutionIntoAbbreviation.fir.kt new file mode 100644 index 00000000000..32741c4edf6 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/capturedTypes/capturedTypesSubstitutionIntoAbbreviation.fir.kt @@ -0,0 +1,31 @@ +typealias Action = (@UnsafeVariance K) -> Unit +typealias Action2 = (@UnsafeVariance K) -> K + +data class Tag(val action: Action) +data class Tag2(val action: Action) +data class Tag3(val action: Action) +data class Tag4(val action: Action) +data class Tag5(val action: Action2) +data class Tag6(val action: Action) +data class Tag7(val action: Action) +data class Tag8(val action: Action2) + +fun getTag(): Tag<*> = Tag {} +fun getTag2(): Tag2<*> = Tag2 {} +fun getTag3(): Tag3<*> = Tag3 {} +fun getTag4(): Tag4<*> = Tag4 {} +fun getTag5(): Tag5<*> = Tag5 { 1 } +fun getTag6(): Tag6<*> = Tag6 { } +fun getTag7(): Tag7<*> = Tag7 { } +fun getTag8(): Tag8<*> = Tag8 { 1 } + +fun main() { + ")!>getTag().action + ")!>getTag2().action + ")!>getTag3().action + ")!>getTag4().action + ")!>getTag5().action + ")!>getTag6().action + ")!>getTag7().action + ")!>getTag8().action +} diff --git a/compiler/testData/diagnostics/tests/inference/capturedTypes/capturedTypesSubstitutionIntoAbbreviation.kt b/compiler/testData/diagnostics/tests/inference/capturedTypes/capturedTypesSubstitutionIntoAbbreviation.kt new file mode 100644 index 00000000000..188a3e3778d --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/capturedTypes/capturedTypesSubstitutionIntoAbbreviation.kt @@ -0,0 +1,31 @@ +typealias Action = (@UnsafeVariance K) -> Unit +typealias Action2 = (@UnsafeVariance K) -> K + +data class Tag(val action: Action) +data class Tag2(val action: Action) +data class Tag3(val action: Action) +data class Tag4(val action: Action) +data class Tag5(val action: Action2) +data class Tag6(val action: Action) +data class Tag7(val action: Action) +data class Tag8(val action: Action2) + +fun getTag(): Tag<*> = Tag {} +fun getTag2(): Tag2<*> = Tag2 {} +fun getTag3(): Tag3<*> = Tag3 {} +fun getTag4(): Tag4<*> = Tag4 {} +fun getTag5(): Tag5<*> = Tag5 { 1 } +fun getTag6(): Tag6<*> = Tag6 { } +fun getTag7(): Tag7<*> = Tag7 { } +fun getTag8(): Tag8<*> = Tag8 { 1 } + +fun main() { + /* = (kotlin.Any?) -> kotlin.Unit */")!>getTag().action + /* = (kotlin.Any?) -> kotlin.Unit */")!>getTag2().action + /* = (kotlin.Any?) -> kotlin.Unit */")!>getTag3().action + /* = (kotlin.Any?) -> kotlin.Unit */")!>getTag4().action + kotlin.Any?")!>getTag5().action + /* = (kotlin.Any?) -> kotlin.Unit */")!>getTag6().action + /* = (kotlin.Any?) -> kotlin.Unit */")!>getTag7().action + kotlin.Any?")!>getTag8().action +} diff --git a/compiler/testData/diagnostics/tests/inference/capturedTypes/capturedTypesSubstitutionIntoAbbreviation.txt b/compiler/testData/diagnostics/tests/inference/capturedTypes/capturedTypesSubstitutionIntoAbbreviation.txt new file mode 100644 index 00000000000..8763b8547b7 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/capturedTypes/capturedTypesSubstitutionIntoAbbreviation.txt @@ -0,0 +1,93 @@ +package + +public fun getTag(): Tag<*> +public fun getTag2(): Tag2<*> +public fun getTag3(): Tag3<*> +public fun getTag4(): Tag4<*> +public fun getTag5(): Tag5<*> +public fun getTag6(): Tag6<*> +public fun getTag7(): Tag7<*> +public fun getTag8(): Tag8<*> +public fun main(): kotlin.Unit + +public final data class Tag { + public constructor Tag(/*0*/ action: Action /* = (@kotlin.UnsafeVariance L) -> kotlin.Unit */) + public final val action: Action /* = (@kotlin.UnsafeVariance L) -> kotlin.Unit */ + public final operator /*synthesized*/ fun component1(): Action /* = (@kotlin.UnsafeVariance L) -> kotlin.Unit */ + public final /*synthesized*/ fun copy(/*0*/ action: Action /* = (@kotlin.UnsafeVariance L) -> kotlin.Unit */ = ...): Tag + public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String +} + +public final data class Tag2 { + public constructor Tag2(/*0*/ action: Action /* = (in @kotlin.UnsafeVariance L) -> kotlin.Unit */) + public final val action: Action /* = (in @kotlin.UnsafeVariance L) -> kotlin.Unit */ + public final operator /*synthesized*/ fun component1(): Action /* = (in @kotlin.UnsafeVariance L) -> kotlin.Unit */ + public final /*synthesized*/ fun copy(/*0*/ action: Action /* = (in @kotlin.UnsafeVariance L) -> kotlin.Unit */ = ...): Tag2 + public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String +} + +public final data class Tag3 { + public constructor Tag3(/*0*/ action: Action /* = (@kotlin.UnsafeVariance L) -> kotlin.Unit */) + public final val action: Action /* = (@kotlin.UnsafeVariance L) -> kotlin.Unit */ + public final operator /*synthesized*/ fun component1(): Action /* = (@kotlin.UnsafeVariance L) -> kotlin.Unit */ + public final /*synthesized*/ fun copy(/*0*/ action: Action /* = (@kotlin.UnsafeVariance L) -> kotlin.Unit */ = ...): Tag3 + public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String +} + +public final data class Tag4 { + public constructor Tag4(/*0*/ action: Action /* = (in @kotlin.UnsafeVariance L) -> kotlin.Unit */) + public final val action: Action /* = (in @kotlin.UnsafeVariance L) -> kotlin.Unit */ + public final operator /*synthesized*/ fun component1(): Action /* = (in @kotlin.UnsafeVariance L) -> kotlin.Unit */ + public final /*synthesized*/ fun copy(/*0*/ action: Action /* = (in @kotlin.UnsafeVariance L) -> kotlin.Unit */ = ...): Tag4 + public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String +} + +public final data class Tag5 { + public constructor Tag5(/*0*/ action: Action2 /* = (@kotlin.UnsafeVariance L) -> L */) + public final val action: Action2 /* = (@kotlin.UnsafeVariance L) -> L */ + public final operator /*synthesized*/ fun component1(): Action2 /* = (@kotlin.UnsafeVariance L) -> L */ + public final /*synthesized*/ fun copy(/*0*/ action: Action2 /* = (@kotlin.UnsafeVariance L) -> L */ = ...): Tag5 + public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String +} + +public final data class Tag6 { + public constructor Tag6(/*0*/ action: Action /* = (in @kotlin.UnsafeVariance L) -> kotlin.Unit */) + public final val action: Action /* = (in @kotlin.UnsafeVariance L) -> kotlin.Unit */ + public final operator /*synthesized*/ fun component1(): Action /* = (in @kotlin.UnsafeVariance L) -> kotlin.Unit */ + public final /*synthesized*/ fun copy(/*0*/ action: Action /* = (in @kotlin.UnsafeVariance L) -> kotlin.Unit */ = ...): Tag6 + public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String +} + +public final data class Tag7 { + public constructor Tag7(/*0*/ action: Action /* = (@kotlin.UnsafeVariance L) -> kotlin.Unit */) + public final val action: Action /* = (@kotlin.UnsafeVariance L) -> kotlin.Unit */ + public final operator /*synthesized*/ fun component1(): Action /* = (@kotlin.UnsafeVariance L) -> kotlin.Unit */ + public final /*synthesized*/ fun copy(/*0*/ action: Action /* = (@kotlin.UnsafeVariance L) -> kotlin.Unit */ = ...): Tag7 + public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String +} + +public final data class Tag8 { + public constructor Tag8(/*0*/ action: Action2 /* = (@kotlin.UnsafeVariance L) -> L */) + public final val action: Action2 /* = (@kotlin.UnsafeVariance L) -> L */ + public final operator /*synthesized*/ fun component1(): Action2 /* = (@kotlin.UnsafeVariance L) -> L */ + public final /*synthesized*/ fun copy(/*0*/ action: Action2 /* = (@kotlin.UnsafeVariance L) -> L */ = ...): Tag8 + public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String +} +public typealias Action = (@kotlin.UnsafeVariance K) -> kotlin.Unit +public typealias Action2 = (@kotlin.UnsafeVariance K) -> K 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 edef6d75d7c..1e2b50cec6e 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 @@ -12432,6 +12432,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/inference/capturedTypes/capturedTypeWithTypeVariableSubtyping.kt"); } + @Test + @TestMetadata("capturedTypesSubstitutionIntoAbbreviation.kt") + public void testCapturedTypesSubstitutionIntoAbbreviation() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/capturedTypes/capturedTypesSubstitutionIntoAbbreviation.kt"); + } + @Test @TestMetadata("capturingFromArgumentOfFlexibleType.kt") public void testCapturingFromArgumentOfFlexibleType() throws Exception { diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index fb58726ad80..be970c35be3 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -13301,6 +13301,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/inference/capturedStarProjection.kt"); } + @TestMetadata("capturedTypesSubstitutionIntoAbbreviation.kt") + public void testCapturedTypesSubstitutionIntoAbbreviation() throws Exception { + runTest("compiler/testData/codegen/box/inference/capturedTypesSubstitutionIntoAbbreviation.kt"); + } + @TestMetadata("coercionToUnitForLambdaReturnTypeWithFlexibleConstraint.kt") public void testCoercionToUnitForLambdaReturnTypeWithFlexibleConstraint() throws Exception { runTest("compiler/testData/codegen/box/inference/coercionToUnitForLambdaReturnTypeWithFlexibleConstraint.kt"); diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 821c5a462e2..778943165cb 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -13301,6 +13301,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/inference/capturedStarProjection.kt"); } + @TestMetadata("capturedTypesSubstitutionIntoAbbreviation.kt") + public void testCapturedTypesSubstitutionIntoAbbreviation() throws Exception { + runTest("compiler/testData/codegen/box/inference/capturedTypesSubstitutionIntoAbbreviation.kt"); + } + @TestMetadata("coercionToUnitForLambdaReturnTypeWithFlexibleConstraint.kt") public void testCoercionToUnitForLambdaReturnTypeWithFlexibleConstraint() throws Exception { runTest("compiler/testData/codegen/box/inference/coercionToUnitForLambdaReturnTypeWithFlexibleConstraint.kt"); diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index b3d257c583b..a500d9a9d3a 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -13301,6 +13301,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/inference/capturedStarProjection.kt"); } + @TestMetadata("capturedTypesSubstitutionIntoAbbreviation.kt") + public void testCapturedTypesSubstitutionIntoAbbreviation() throws Exception { + runTest("compiler/testData/codegen/box/inference/capturedTypesSubstitutionIntoAbbreviation.kt"); + } + @TestMetadata("coercionToUnitForLambdaReturnTypeWithFlexibleConstraint.kt") public void testCoercionToUnitForLambdaReturnTypeWithFlexibleConstraint() throws Exception { runTest("compiler/testData/codegen/box/inference/coercionToUnitForLambdaReturnTypeWithFlexibleConstraint.kt"); diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/calls/inference/CapturedTypeConstructor.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/calls/inference/CapturedTypeConstructor.kt index efe2dcf1829..d9469f312e3 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/calls/inference/CapturedTypeConstructor.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/calls/inference/CapturedTypeConstructor.kt @@ -122,7 +122,7 @@ fun TypeSubstitution.wrapWithCapturingSubstitution(needApproximation: Boolean = this.arguments.zip(this.parameters).map { it.first.createCapturedIfNeeded(it.second) }.toTypedArray(), - approximateCapturedTypes = needApproximation + approximateContravariantCapturedTypes = needApproximation ) else object : DelegatedTypeSubstitution(this@wrapWithCapturingSubstitution) { diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/TypeSubstitution.kt b/core/descriptors/src/org/jetbrains/kotlin/types/TypeSubstitution.kt index 645874abcd1..cf9b1cc6ffd 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/TypeSubstitution.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/TypeSubstitution.kt @@ -88,7 +88,7 @@ abstract class TypeConstructorSubstitution : TypeSubstitution() { class IndexedParametersSubstitution( val parameters: Array, val arguments: Array, - private val approximateCapturedTypes: Boolean = false + private val approximateContravariantCapturedTypes: Boolean = false ) : TypeSubstitution() { init { assert(parameters.size <= arguments.size) { @@ -103,7 +103,7 @@ class IndexedParametersSubstitution( override fun isEmpty(): Boolean = arguments.isEmpty() - override fun approximateContravariantCapturedTypes() = approximateCapturedTypes + override fun approximateContravariantCapturedTypes() = approximateContravariantCapturedTypes override fun get(key: KotlinType): TypeProjection? { val parameter = key.constructor.declarationDescriptor as? TypeParameterDescriptor ?: return null diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/TypeSubstitutor.java b/core/descriptors/src/org/jetbrains/kotlin/types/TypeSubstitutor.java index 5997d1fed3e..da175c6f513 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/TypeSubstitutor.java +++ b/core/descriptors/src/org/jetbrains/kotlin/types/TypeSubstitutor.java @@ -54,6 +54,19 @@ public class TypeSubstitutor implements TypeSubstitutorMarker { return new TypeSubstitutor(substitution); } + @NotNull + public TypeSubstitutor replaceWithNonApproximatingSubstitution() { + if (!(substitution instanceof IndexedParametersSubstitution) || !substitution.approximateContravariantCapturedTypes()) return this; + + return new TypeSubstitutor( + new IndexedParametersSubstitution( + ((IndexedParametersSubstitution) substitution).getParameters(), + ((IndexedParametersSubstitution) substitution).getArguments(), + false + ) + ); + } + @NotNull public static TypeSubstitutor createChainedSubstitutor(@NotNull TypeSubstitution first, @NotNull TypeSubstitution second) { return create(DisjointKeysUnionTypeSubstitution.create(first, second)); @@ -302,7 +315,9 @@ public class TypeSubstitutor implements TypeSubstitutorMarker { KotlinType substitutedAbbreviation = null; SimpleType abbreviation = SpecialTypesKt.getAbbreviation(type); if (abbreviation != null) { - substitutedAbbreviation = substitute(abbreviation, Variance.INVARIANT); + // We shouldn't approximate abbreviation at the top-level as they can't be projected: below we substitute this always as invariant + TypeSubstitutor substitutorForAbbreviation = replaceWithNonApproximatingSubstitution(); + substitutedAbbreviation = substitutorForAbbreviation.substitute(abbreviation, Variance.INVARIANT); } List substitutedArguments = substituteTypeArguments( 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 23e8c5b7443..5e88c866dd6 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 @@ -11386,6 +11386,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes runTest("compiler/testData/codegen/box/inference/capturedStarProjection.kt"); } + @TestMetadata("capturedTypesSubstitutionIntoAbbreviation.kt") + public void testCapturedTypesSubstitutionIntoAbbreviation() throws Exception { + runTest("compiler/testData/codegen/box/inference/capturedTypesSubstitutionIntoAbbreviation.kt"); + } + @TestMetadata("coercionToUnitWithLastLambdaExpression.kt") public void testCoercionToUnitWithLastLambdaExpression() throws Exception { runTest("compiler/testData/codegen/box/inference/coercionToUnitWithLastLambdaExpression.kt"); 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 e22daf5b09a..6bf98298989 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 @@ -11386,6 +11386,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTest("compiler/testData/codegen/box/inference/capturedStarProjection.kt"); } + @TestMetadata("capturedTypesSubstitutionIntoAbbreviation.kt") + public void testCapturedTypesSubstitutionIntoAbbreviation() throws Exception { + runTest("compiler/testData/codegen/box/inference/capturedTypesSubstitutionIntoAbbreviation.kt"); + } + @TestMetadata("coercionToUnitWithLastLambdaExpression.kt") public void testCoercionToUnitWithLastLambdaExpression() throws Exception { runTest("compiler/testData/codegen/box/inference/coercionToUnitWithLastLambdaExpression.kt"); 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 f74d83ccefc..fb64cbbe42e 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 @@ -11451,6 +11451,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTest("compiler/testData/codegen/box/inference/capturedStarProjection.kt"); } + @TestMetadata("capturedTypesSubstitutionIntoAbbreviation.kt") + public void testCapturedTypesSubstitutionIntoAbbreviation() throws Exception { + runTest("compiler/testData/codegen/box/inference/capturedTypesSubstitutionIntoAbbreviation.kt"); + } + @TestMetadata("coercionToUnitWithLastLambdaExpression.kt") public void testCoercionToUnitWithLastLambdaExpression() throws Exception { runTest("compiler/testData/codegen/box/inference/coercionToUnitWithLastLambdaExpression.kt"); 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 d93848261f8..5f97f29546a 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 @@ -6092,6 +6092,11 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest runTest("compiler/testData/codegen/box/inference/capturedStarProjection.kt"); } + @TestMetadata("capturedTypesSubstitutionIntoAbbreviation.kt") + public void testCapturedTypesSubstitutionIntoAbbreviation() throws Exception { + runTest("compiler/testData/codegen/box/inference/capturedTypesSubstitutionIntoAbbreviation.kt"); + } + @TestMetadata("earlyReturnInsideCrossinlineLambda.kt") public void testEarlyReturnInsideCrossinlineLambda() throws Exception { runTest("compiler/testData/codegen/box/inference/earlyReturnInsideCrossinlineLambda.kt");