diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/KtSymbolByFirBuilder.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/KtSymbolByFirBuilder.kt index 52017a82ac7..ba338880ca3 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/KtSymbolByFirBuilder.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/KtSymbolByFirBuilder.kt @@ -33,7 +33,7 @@ import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.impl.FirFieldImpl import org.jetbrains.kotlin.fir.declarations.impl.FirOuterClassTypeParameterRef -import org.jetbrains.kotlin.fir.diagnostics.ConeCannotInferParameterType +import org.jetbrains.kotlin.fir.diagnostics.ConeCannotInferTypeParameterType import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic import org.jetbrains.kotlin.fir.java.declarations.FirJavaField import org.jetbrains.kotlin.fir.originalForSubstitutionOverride @@ -458,7 +458,7 @@ internal class KtSymbolByFirBuilder constructor( is ConeTypeVariableType -> { val diagnostic = when ( val typeParameter = coneType.lookupTag.originalTypeParameter) { null -> ConeSimpleDiagnostic("Cannot infer parameter type for ${coneType.lookupTag.debugName}") - else -> ConeCannotInferParameterType((typeParameter as ConeTypeParameterLookupTag).typeParameterSymbol) + else -> ConeCannotInferTypeParameterType((typeParameter as ConeTypeParameterLookupTag).typeParameterSymbol) } buildKtType(ConeErrorType(diagnostic, isUninferredParameter = true, attributes = coneType.attributes)) } diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/types/KtFirTypeErrorType.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/types/KtFirTypeErrorType.kt index 5ca80a60328..cf7326eb187 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/types/KtFirTypeErrorType.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/types/KtFirTypeErrorType.kt @@ -13,7 +13,7 @@ import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion import org.jetbrains.kotlin.analysis.api.types.KtTypeErrorType import org.jetbrains.kotlin.analysis.api.types.KtTypeNullability -import org.jetbrains.kotlin.fir.diagnostics.ConeCannotInferParameterType +import org.jetbrains.kotlin.fir.diagnostics.ConeCannotInferTypeParameterType import org.jetbrains.kotlin.fir.types.ConeErrorType import org.jetbrains.kotlin.fir.types.renderForDebugging @@ -28,7 +28,7 @@ internal class KtFirTypeErrorType( override fun tryRenderAsNonErrorType(): String? = withValidityAssertion { when (val diagnostic = coneType.diagnostic) { - is ConeCannotInferParameterType -> diagnostic.typeParameter.name.asString() + is ConeCannotInferTypeParameterType -> diagnostic.typeParameter.name.asString() else -> null } } 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 eeed18fc37b..802f9d7e89b 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 @@ -11858,6 +11858,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag runTest("compiler/testData/diagnostics/tests/functionLiterals/kt51317.kt"); } + @Test + @TestMetadata("kt56138.kt") + public void testKt56138() throws Exception { + runTest("compiler/testData/diagnostics/tests/functionLiterals/kt56138.kt"); + } + @Test @TestMetadata("kt6541_extensionForExtensionFunction.kt") public void testKt6541_extensionForExtensionFunction() 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 e4ba5a0c68f..5bbd015b7df 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 @@ -11864,6 +11864,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti runTest("compiler/testData/diagnostics/tests/functionLiterals/kt51317.kt"); } + @Test + @TestMetadata("kt56138.kt") + public void testKt56138() throws Exception { + runTest("compiler/testData/diagnostics/tests/functionLiterals/kt56138.kt"); + } + @Test @TestMetadata("kt6541_extensionForExtensionFunction.kt") public void testKt6541_extensionForExtensionFunction() 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 41ea34f4734..5a3084c8359 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 @@ -11858,6 +11858,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac runTest("compiler/testData/diagnostics/tests/functionLiterals/kt51317.kt"); } + @Test + @TestMetadata("kt56138.kt") + public void testKt56138() throws Exception { + runTest("compiler/testData/diagnostics/tests/functionLiterals/kt56138.kt"); + } + @Test @TestMetadata("kt6541_extensionForExtensionFunction.kt") public void testKt6541_extensionForExtensionFunction() throws Exception { diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt index ca3d50383e5..21b5decc275 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt @@ -24,7 +24,6 @@ import org.jetbrains.kotlin.fir.resolve.inference.model.ConeArgumentConstraintPo import org.jetbrains.kotlin.fir.resolve.inference.model.ConeExpectedTypeConstraintPosition import org.jetbrains.kotlin.fir.resolve.inference.model.ConeLambdaArgumentConstraintPosition import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag -import org.jetbrains.kotlin.fir.symbols.impl.FirBackingFieldSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol @@ -109,7 +108,8 @@ private fun ConeDiagnostic.toKtDiagnostic( } is ConeDestructuringDeclarationsOnTopLevel -> FirSyntaxErrors.SYNTAX.createOn(source) - is ConeCannotInferParameterType -> FirErrors.CANNOT_INFER_PARAMETER_TYPE.createOn(source) + is ConeCannotInferTypeParameterType -> FirErrors.CANNOT_INFER_PARAMETER_TYPE.createOn(source) + is ConeCannotInferValueParameterType -> FirErrors.CANNOT_INFER_PARAMETER_TYPE.createOn(source) is ConeInstanceAccessBeforeSuperCall -> FirErrors.INSTANCE_ACCESS_BEFORE_SUPER_CALL.createOn(source, this.target) is ConeStubDiagnostic -> null is ConeIntermediateDiagnostic -> null diff --git a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt index 0583c5710e1..396ee88acc0 100644 --- a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt +++ b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt @@ -2318,16 +2318,20 @@ class DeclarationsConverter( val name = convertValueParameterName(identifier.nameAsSafeName(), identifier, valueParameterDeclaration) + val valueParameterSource = valueParameter.toFirSourceElement() return ValueParameter( isVal = isVal, isVar = isVar, modifiers = modifiers, returnTypeRef = firType ?: when { + valueParameterDeclaration == ValueParameterDeclaration.LAMBDA -> buildImplicitTypeRef { + source = valueParameterSource.fakeElement(KtFakeSourceElementKind.ImplicitReturnTypeOfLambdaValueParameter) + } valueParameterDeclaration.shouldExplicitParameterTypeBePresent -> createNoTypeForParameterTypeRef() else -> implicitType }, - source = valueParameter.toFirSourceElement(), + source = valueParameterSource, moduleData = baseModuleData, isFromPrimaryConstructor = valueParameterDeclaration == ValueParameterDeclaration.PRIMARY_CONSTRUCTOR, additionalAnnotations = additionalAnnotations, diff --git a/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt b/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt index b357631c0e2..a6cb463a20b 100644 --- a/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt +++ b/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt @@ -1583,7 +1583,7 @@ open class RawFirBuilder( multiParameter } else { val typeRef = valueParameter.typeReference?.convertSafe() ?: buildImplicitTypeRef { - source = implicitTypeRefSource + source = valueParameter.toFirSourceElement().fakeElement(KtFakeSourceElementKind.ImplicitReturnTypeOfLambdaValueParameter) } convertValueParameter(valueParameter, symbol, typeRef, ValueParameterDeclaration.LAMBDA) } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/ConstraintSystemCompleter.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/ConstraintSystemCompleter.kt index 916d8d63754..a93ca1b81cb 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/ConstraintSystemCompleter.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/ConstraintSystemCompleter.kt @@ -7,7 +7,7 @@ package org.jetbrains.kotlin.fir.resolve.inference import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.fir.FirElement -import org.jetbrains.kotlin.fir.diagnostics.ConeCannotInferParameterType +import org.jetbrains.kotlin.fir.diagnostics.ConeCannotInferTypeParameterType import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind import org.jetbrains.kotlin.fir.expressions.* @@ -459,7 +459,7 @@ class ConstraintSystemCompleter(components: BodyResolveComponents, private val c ): ConeErrorType { val diagnostic = when (typeParameterSymbol) { null -> ConeSimpleDiagnostic(message, DiagnosticKind.CannotInferParameterType) - else -> ConeCannotInferParameterType( + else -> ConeCannotInferTypeParameterType( typeParameterSymbol, message, ) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirCallCompleter.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirCallCompleter.kt index 15117becc1a..ca42ce6fed6 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirCallCompleter.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirCallCompleter.kt @@ -332,7 +332,7 @@ class FirCallCompleter( lambdaArgument.valueParameters.forEachIndexed { index, parameter -> val newReturnType = parameters[index].approximateLambdaInputType() val newReturnTypeRef = if (parameter.returnTypeRef is FirImplicitTypeRef) { - newReturnType.toFirResolvedTypeRef(parameter.source) + newReturnType.toFirResolvedTypeRef(parameter.source?.fakeElement(KtFakeSourceElementKind.ImplicitReturnTypeOfLambdaValueParameter)) } else parameter.returnTypeRef.resolvedTypeFromPrototype(newReturnType) parameter.replaceReturnTypeRef(newReturnTypeRef) lookupTracker?.recordTypeResolveAsLookup(newReturnTypeRef, parameter.source, fileSource) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/InferenceUtils.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/InferenceUtils.kt index d106755a551..425725e9ff7 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/InferenceUtils.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/InferenceUtils.kt @@ -6,8 +6,7 @@ package org.jetbrains.kotlin.fir.resolve.inference import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction -import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic -import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind +import org.jetbrains.kotlin.fir.diagnostics.ConeCannotInferValueParameterType import org.jetbrains.kotlin.fir.expressions.FirReturnExpression import org.jetbrains.kotlin.fir.expressions.impl.FirUnitExpression import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents @@ -85,9 +84,7 @@ fun extractLambdaInfoFromFunctionType( argumentValueParameters.mapIndexed { index, parameter -> parameter.returnTypeRef.coneTypeSafe() ?: expectedParameters.getOrNull(index) - ?: ConeErrorType( - ConeSimpleDiagnostic("Cannot infer type for parameter ${parameter.name}", DiagnosticKind.CannotInferParameterType) - ) + ?: ConeErrorType(ConeCannotInferValueParameterType(parameter.symbol)) } } diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/diagnostics/ConeSimpleDiagnostic.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/diagnostics/ConeSimpleDiagnostic.kt index 99f51c50079..827432c355e 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/diagnostics/ConeSimpleDiagnostic.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/diagnostics/ConeSimpleDiagnostic.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.diagnostics import org.jetbrains.kotlin.KtSourceElement import org.jetbrains.kotlin.builtins.functions.FunctionTypeKind import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirValueParameterSymbol import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.name.Name @@ -23,11 +24,16 @@ class ConeUnderscoreIsReserved(source: KtSourceElement) : ConeDiagnosticWithSour override val reason: String get() = "Names _, __, ___, ..., are reserved in Kotlin" } -class ConeCannotInferParameterType( +class ConeCannotInferTypeParameterType( val typeParameter: FirTypeParameterSymbol, override val reason: String = "Cannot infer type for parameter ${typeParameter.name}" ) : ConeDiagnostic +class ConeCannotInferValueParameterType( + val valueParameter: FirValueParameterSymbol, + override val reason: String = "Cannot infer type for parameter ${valueParameter.name}" +) : ConeDiagnostic + class ConeUnderscoreUsageWithoutBackticks(source: KtSourceElement) : ConeDiagnosticWithSource(source) { override val reason: String get() = "Names _, __, ___, ... can be used only in back-ticks (`_`, `__`, `___`, ...)" } @@ -78,7 +84,7 @@ enum class DiagnosticKind { Java, SuperNotAllowed, ValueParameterWithNoTypeAnnotation, - CannotInferParameterType, + CannotInferParameterType, // TODO: replace this with ConeCannotInferValueParameterType and ConeCannotInferTypeParameterType IllegalProjectionUsage, MissingStdlibClass, NotASupertype, diff --git a/compiler/frontend.common/src/org/jetbrains/kotlin/KtSourceElement.kt b/compiler/frontend.common/src/org/jetbrains/kotlin/KtSourceElement.kt index 4977a93c6d0..f8c771dbae9 100644 --- a/compiler/frontend.common/src/org/jetbrains/kotlin/KtSourceElement.kt +++ b/compiler/frontend.common/src/org/jetbrains/kotlin/KtSourceElement.kt @@ -248,6 +248,9 @@ sealed class KtFakeSourceElementKind(final override val shouldSkipErrorTypeRepor // for when on the LHS of an assignment an error expression appears object AssignmentLValueError : KtFakeSourceElementKind() + + // for return type of value parameters in lambdas + object ImplicitReturnTypeOfLambdaValueParameter : KtFakeSourceElementKind() } sealed class AbstractKtSourceElement { diff --git a/compiler/testData/diagnostics/tests/functionLiterals/kt56138.fir.kt b/compiler/testData/diagnostics/tests/functionLiterals/kt56138.fir.kt new file mode 100644 index 00000000000..a2a0e904dec --- /dev/null +++ b/compiler/testData/diagnostics/tests/functionLiterals/kt56138.fir.kt @@ -0,0 +1,37 @@ +// SKIP_TXT +// ISSUE: KT-56138 + +fun takeLambda1(f: String.() -> String) {} +fun takeLambda2(f: String.(String) -> String) {} + +fun test_1() { + val x1: String.(String) -> String = { str, str2 -> "this" } + val x2: String.() -> String = { it } + val x3: String.() -> String = { x -> "x" } +} + +fun test_2() { + takeLambda2 { str, str2 -> "this" } + takeLambda1 { it } + takeLambda1 { x -> "x" } +} + +fun test_3(b: Boolean) { + val x1: String.(String) -> String = if (b) { + { str, str2 -> "this" } + } else { + { str, str2 -> "this" } + } + + val x2: String.() -> String = if (b) { + { it } + } else { + { it } + } + + val x3: String.() -> String = if (b) { + { x -> "x" } + } else { + { x -> "x" } + } +} diff --git a/compiler/testData/diagnostics/tests/functionLiterals/kt56138.kt b/compiler/testData/diagnostics/tests/functionLiterals/kt56138.kt new file mode 100644 index 00000000000..034973b10b0 --- /dev/null +++ b/compiler/testData/diagnostics/tests/functionLiterals/kt56138.kt @@ -0,0 +1,37 @@ +// SKIP_TXT +// ISSUE: KT-56138 + +fun takeLambda1(f: String.() -> String) {} +fun takeLambda2(f: String.(String) -> String) {} + +fun test_1() { + val x1: String.(String) -> String = { str, str2 -> "this" } + val x2: String.() -> String = { it } + val x3: String.() -> String = { x -> "x" } +} + +fun test_2() { + takeLambda2 { str, str2 -> "this" } + takeLambda1 { it } + takeLambda1 { x -> "x" } +} + +fun test_3(b: Boolean) { + val x1: String.(String) -> String = if (b) { + { str, str2 -> "this" } + } else { + { str, str2 -> "this" } + } + + val x2: String.() -> String = if (b) { + { it } + } else { + { it } + } + + val x3: String.() -> String = if (b) { + { x -> "x" } + } else { + { x -> "x" } + } +} 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 359dab22af5..291b17e4374 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 @@ -11864,6 +11864,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/functionLiterals/kt51317.kt"); } + @Test + @TestMetadata("kt56138.kt") + public void testKt56138() throws Exception { + runTest("compiler/testData/diagnostics/tests/functionLiterals/kt56138.kt"); + } + @Test @TestMetadata("kt6541_extensionForExtensionFunction.kt") public void testKt6541_extensionForExtensionFunction() throws Exception {