diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java index 48738acd6b2..166f2e3d48b 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java @@ -15499,6 +15499,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag runTest("compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/nullableEmptyIntersection.kt"); } + @Test + @TestMetadata("recursiveTypeParameters.kt") + public void testRecursiveTypeParameters() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/recursiveTypeParameters.kt"); + } + @Test @TestMetadata("selectFromCovariantAndContravariantTypes.kt") public void testSelectFromCovariantAndContravariantTypes() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java index 056e1c5ac7d..472f27f9ff3 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 @@ -15499,6 +15499,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti runTest("compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/nullableEmptyIntersection.kt"); } + @Test + @TestMetadata("recursiveTypeParameters.kt") + public void testRecursiveTypeParameters() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/recursiveTypeParameters.kt"); + } + @Test @TestMetadata("selectFromCovariantAndContravariantTypes.kt") public void testSelectFromCovariantAndContravariantTypes() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java index 31ba7d7d650..ed4da1f2235 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 @@ -15499,6 +15499,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac runTest("compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/nullableEmptyIntersection.kt"); } + @Test + @TestMetadata("recursiveTypeParameters.kt") + public void testRecursiveTypeParameters() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/recursiveTypeParameters.kt"); + } + @Test @TestMetadata("selectFromCovariantAndContravariantTypes.kt") public void testSelectFromCovariantAndContravariantTypes() throws Exception { diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ConeInferenceContext.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ConeInferenceContext.kt index d7136f7dc8d..9208316c375 100644 --- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ConeInferenceContext.kt +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ConeInferenceContext.kt @@ -19,7 +19,6 @@ import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl import org.jetbrains.kotlin.name.StandardClassIds -import org.jetbrains.kotlin.resolve.calls.NewCommonSuperTypeCalculator.commonSuperType import org.jetbrains.kotlin.types.AbstractTypeChecker import org.jetbrains.kotlin.types.AbstractTypeRefiner import org.jetbrains.kotlin.types.TypeCheckerState @@ -389,7 +388,21 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo val typeParameterErasureMap = this.extractTypeParameters() .map { (it as ConeTypeParameterLookupTag).typeParameterSymbol } .eraseToUpperBoundsAssociated(session, intersectUpperBounds = true, eraseRecursively = true) - return ConeSubstitutorByMap(typeParameterErasureMap, session).safeSubstitute(this) + val substitutor by lazy { ConeSubstitutorByMap(typeParameterErasureMap, session) } + val typeWithErasedTypeParameters = if (argumentsCount() != 0) { + replaceArgumentsDeeply { + val type = it.getType() + val typeParameter = + (type.typeConstructor().getTypeParameterClassifier() as? ConeTypeParameterLookupTag)?.typeParameterSymbol + if (typeParameter != null) { + createTypeArgument(substitutor.safeSubstitute(type), TypeVariance.OUT) + } else it + } + } else if (typeConstructor().isTypeParameterTypeConstructor()) { + substitutor.safeSubstitute(this) + } else this + + return typeWithErasedTypeParameters } override fun TypeConstructorMarker.isTypeParameterTypeConstructor(): Boolean { diff --git a/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/recursiveTypeParameters.kt b/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/recursiveTypeParameters.kt new file mode 100644 index 00000000000..0f69bdca898 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/recursiveTypeParameters.kt @@ -0,0 +1,7 @@ +// FIR_IDENTICAL +// WITH_STDLIB +// FULL_JDK + +import java.util.* + +fun , V> enumMapOf(vararg pairs: Pair): EnumMap = EnumMap(mapOf(*pairs)) diff --git a/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/recursiveTypeParameters.txt b/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/recursiveTypeParameters.txt new file mode 100644 index 00000000000..9386d923937 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/recursiveTypeParameters.txt @@ -0,0 +1,3 @@ +package + +public fun , /*1*/ V> enumMapOf(/*0*/ vararg pairs: kotlin.Pair /*kotlin.Array>*/): java.util.EnumMap 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 acf14e186fd..9063004c811 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 @@ -15505,6 +15505,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/nullableEmptyIntersection.kt"); } + @Test + @TestMetadata("recursiveTypeParameters.kt") + public void testRecursiveTypeParameters() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/recursiveTypeParameters.kt"); + } + @Test @TestMetadata("selectFromCovariantAndContravariantTypes.kt") public void testSelectFromCovariantAndContravariantTypes() throws Exception { diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/checker/ClassicTypeSystemContext.kt b/core/descriptors/src/org/jetbrains/kotlin/types/checker/ClassicTypeSystemContext.kt index e9950501ed7..431477879db 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/checker/ClassicTypeSystemContext.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/checker/ClassicTypeSystemContext.kt @@ -716,7 +716,9 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSy ) val typeParameters = this.extractTypeParameters() .map { it as TypeParameterDescriptor } - .associateWith { TypeProjectionImpl(eraser.getErasedUpperBound(it, ErasureTypeAttributes(TypeUsage.COMMON))) } + .associateWith { + TypeProjectionImpl(Variance.OUT_VARIANCE, eraser.getErasedUpperBound(it, ErasureTypeAttributes(TypeUsage.COMMON))) + } return TypeConstructorSubstitution.createByParametersMap(typeParameters).buildSubstitutor().safeSubstitute(this) }