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 74b8a8c8f91..738a4e28903 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 @@ -12861,6 +12861,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/inference"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true); } + @Test + @TestMetadata("annotatedUnderscoredTypeArgument.kt") + public void testAnnotatedUnderscoredTypeArgument() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/annotatedUnderscoredTypeArgument.kt"); + } + @Test @TestMetadata("cannotCompleteResolveAmbiguity.kt") public void testCannotCompleteResolveAmbiguity() 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 aaef0330d27..cf2ef27371e 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 @@ -12861,6 +12861,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/inference"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true); } + @Test + @TestMetadata("annotatedUnderscoredTypeArgument.kt") + public void testAnnotatedUnderscoredTypeArgument() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/annotatedUnderscoredTypeArgument.kt"); + } + @Test @TestMetadata("cannotCompleteResolveAmbiguity.kt") public void testCannotCompleteResolveAmbiguity() 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 3f07792f587..b4c25783774 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 @@ -12861,6 +12861,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/inference"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true); } + @Test + @TestMetadata("annotatedUnderscoredTypeArgument.kt") + public void testAnnotatedUnderscoredTypeArgument() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/annotatedUnderscoredTypeArgument.kt"); + } + @Test @TestMetadata("cannotCompleteResolveAmbiguity.kt") public void testCannotCompleteResolveAmbiguity() throws Exception { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeResolver.kt index 5743e9128aa..020c4b9c43a 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/TypeResolver.kt @@ -118,7 +118,7 @@ class TypeResolver( val resolvedTypeSlice = if (c.abbreviated) BindingContext.ABBREVIATED_TYPE else BindingContext.TYPE - val annotations = resolveTypeAnnotations(c, typeReference) + val annotations = resolveTypeAnnotations(c.trace, c.scope, typeReference) val type = resolveTypeElement(c, annotations, typeReference.modifierList, typeReference.typeElement) c.trace.recordScope(c.scope, typeReference) @@ -158,7 +158,7 @@ class TypeResolver( } } - private fun resolveTypeAnnotations(c: TypeResolutionContext, modifierListsOwner: KtElementImplStub<*>): Annotations { + fun resolveTypeAnnotations(trace: BindingTrace, scope: LexicalScope, modifierListsOwner: KtElementImplStub<*>): Annotations { val modifierLists = modifierListsOwner.getAllModifierLists() var result = Annotations.EMPTY @@ -178,16 +178,16 @@ class TypeResolver( // `targetType.stub == null` means that we don't apply this check for files that are built with stubs (that aren't opened in IDE and not in compile time) if (targetType is KtFunctionType && targetType.stub == null && annotationEntries != null) { - checkNonParenthesizedAnnotationsOnFunctionalType(targetType, annotationEntries, c.trace) + checkNonParenthesizedAnnotationsOnFunctionalType(targetType, annotationEntries, trace) } } for (modifierList in modifierLists) { if (isSplitModifierList) { - c.trace.report(MODIFIER_LIST_NOT_ALLOWED.on(modifierList)) + trace.report(MODIFIER_LIST_NOT_ALLOWED.on(modifierList)) } - val annotations = annotationResolver.resolveAnnotationsWithoutArguments(c.scope, modifierList.annotationEntries, c.trace) + val annotations = annotationResolver.resolveAnnotationsWithoutArguments(scope, modifierList.annotationEntries, trace) result = composeAnnotations(result, annotations) isSplitModifierList = true @@ -285,7 +285,10 @@ class TypeResolver( c.trace.report(MODIFIER_LIST_NOT_ALLOWED.on(innerModifierList)) } - val innerAnnotations = composeAnnotations(annotations, resolveTypeAnnotations(c, typeElement as KtElementImplStub<*>)) + val innerAnnotations = composeAnnotations( + annotations, + resolveTypeAnnotations(c.trace, c.scope, typeElement as KtElementImplStub<*>) + ) return resolveTypeElement(c, innerAnnotations, outerModifierList ?: innerModifierList, innerType) } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/PSICallResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/PSICallResolver.kt index b46fa112350..54f3e44289f 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/PSICallResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/PSICallResolver.kt @@ -20,8 +20,6 @@ import org.jetbrains.kotlin.resolve.calls.ArgumentTypeResolver import org.jetbrains.kotlin.resolve.calls.CallTransformer import org.jetbrains.kotlin.resolve.calls.KotlinCallResolver import org.jetbrains.kotlin.resolve.calls.SPECIAL_FUNCTION_NAMES -import org.jetbrains.kotlin.resolve.calls.util.isBinaryRemOperator -import org.jetbrains.kotlin.resolve.calls.util.* import org.jetbrains.kotlin.resolve.calls.components.InferenceSession import org.jetbrains.kotlin.resolve.calls.components.PostponedArgumentsAnalyzer import org.jetbrains.kotlin.resolve.calls.components.candidate.ResolutionCandidate @@ -37,11 +35,12 @@ import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory import org.jetbrains.kotlin.resolve.calls.tasks.DynamicCallableDescriptors import org.jetbrains.kotlin.resolve.calls.tasks.OldResolutionCandidate import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategy -import org.jetbrains.kotlin.resolve.calls.util.CallMaker +import org.jetbrains.kotlin.resolve.calls.util.* import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns import org.jetbrains.kotlin.resolve.descriptorUtil.isUnderscoreNamed +import org.jetbrains.kotlin.resolve.lazy.ForceResolveUtil import org.jetbrains.kotlin.resolve.scopes.* import org.jetbrains.kotlin.resolve.scopes.receivers.* import org.jetbrains.kotlin.types.* @@ -687,9 +686,14 @@ class PSICallResolver( } ModifierCheckerCore.check(projection, context.trace, null, languageVersionSettings) - val typeReference = projection.typeReference + val typeReference = projection.typeReference ?: return@map TypeArgumentPlaceholder - if (typeReference == null || typeReference.isPlaceholder) return@map TypeArgumentPlaceholder + if (typeReference.isPlaceholder) { + ForceResolveUtil.forceResolveAllContents( + typeResolver.resolveTypeAnnotations(context.trace, context.scope, typeReference) + ) + return@map TypeArgumentPlaceholder + } SimpleTypeArgumentImpl(projection, resolveType(context, typeReference, typeResolver)) } diff --git a/compiler/psi/src/org/jetbrains/kotlin/psi/KtTypeReference.kt b/compiler/psi/src/org/jetbrains/kotlin/psi/KtTypeReference.kt index f05a39daa82..63edcf068a1 100644 --- a/compiler/psi/src/org/jetbrains/kotlin/psi/KtTypeReference.kt +++ b/compiler/psi/src/org/jetbrains/kotlin/psi/KtTypeReference.kt @@ -39,7 +39,7 @@ class KtTypeReference : KtModifierListOwnerStub()?.isPlaceholder == true + get() = typeElement?.findDescendantOfType()?.isPlaceholder == true val typeElement: KtTypeElement? get() = KtStubbedPsiUtil.getStubOrPsiChild(this, KtStubElementTypes.TYPE_ELEMENT_TYPES, KtTypeElement.ARRAY_FACTORY) diff --git a/compiler/testData/diagnostics/tests/inference/annotatedUnderscoredTypeArgument.kt b/compiler/testData/diagnostics/tests/inference/annotatedUnderscoredTypeArgument.kt new file mode 100644 index 00000000000..92db6a5a9d7 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/annotatedUnderscoredTypeArgument.kt @@ -0,0 +1,13 @@ +// !DIAGNOSTICS: -UNCHECKED_CAST +// FIR_IDENTICAL +// WITH_RUNTIME + +fun foo(x: (K) -> T): Pair = (1 as K) to (1f as T) + +@Target(AnnotationTarget.TYPE) +annotation class Anno + +fun box(): String { + val x = foo<@Anno Int, @Anno _> { it.toFloat() } + return "OK" +} diff --git a/compiler/testData/diagnostics/tests/inference/annotatedUnderscoredTypeArgument.txt b/compiler/testData/diagnostics/tests/inference/annotatedUnderscoredTypeArgument.txt new file mode 100644 index 00000000000..aaa635e675b --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/annotatedUnderscoredTypeArgument.txt @@ -0,0 +1,11 @@ +package + +public fun box(): kotlin.String +public fun foo(/*0*/ x: (K) -> T): kotlin.Pair + +@kotlin.annotation.Target(allowedTargets = {AnnotationTarget.TYPE}) public final annotation class Anno : kotlin.Annotation { + public constructor Anno() + 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 +} 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 88ea4fbb9cc..e34a8f24092 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 @@ -12867,6 +12867,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/inference"), Pattern.compile("^(.*)\\.kts?$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true); } + @Test + @TestMetadata("annotatedUnderscoredTypeArgument.kt") + public void testAnnotatedUnderscoredTypeArgument() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/annotatedUnderscoredTypeArgument.kt"); + } + @Test @TestMetadata("cannotCompleteResolveAmbiguity.kt") public void testCannotCompleteResolveAmbiguity() throws Exception {