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 01b2eaf19d2..57a5a1f8ccd 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 @@ -125,6 +125,7 @@ private fun ConeDiagnostic.toKtDiagnostic( is ConeDestructuringDeclarationsOnTopLevel -> null // TODO Currently a parsing error. Would be better to report here instead KT-58563 is ConeCannotInferTypeParameterType -> FirErrors.CANNOT_INFER_PARAMETER_TYPE.createOn(source) is ConeCannotInferValueParameterType -> FirErrors.CANNOT_INFER_PARAMETER_TYPE.createOn(source) + is ConeCannotInferReceiverParameterType -> FirErrors.CANNOT_INFER_PARAMETER_TYPE.createOn(source) is ConeTypeVariableTypeIsNotInferred -> FirErrors.INFERENCE_ERROR.createOn(callOrAssignmentSource ?: source) is ConeInstanceAccessBeforeSuperCall -> FirErrors.INSTANCE_ACCESS_BEFORE_SUPER_CALL.createOn(source, this.target) is ConeStubDiagnostic -> null 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 33d2e85e208..1d5f82e5653 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 @@ -15,6 +15,8 @@ import org.jetbrains.kotlin.fir.declarations.FirFunction import org.jetbrains.kotlin.fir.declarations.FirResolvePhase import org.jetbrains.kotlin.fir.declarations.builder.buildContextReceiver import org.jetbrains.kotlin.fir.declarations.builder.buildValueParameter +import org.jetbrains.kotlin.fir.diagnostics.ConeCannotInferReceiverParameterType +import org.jetbrains.kotlin.fir.diagnostics.ConeCannotInferValueParameterType import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.resolve.ResolutionMode import org.jetbrains.kotlin.fir.resolve.calls.* @@ -263,9 +265,9 @@ class FirCallCompleter( containingFunctionSymbol = lambdaArgument.symbol moduleData = session.moduleData origin = FirDeclarationOrigin.Source - returnTypeRef = itType.approximateLambdaInputType().toFirResolvedTypeRef() this.name = name symbol = FirValueParameterSymbol(name) + returnTypeRef = itType.approximateLambdaInputType(symbol).toFirResolvedTypeRef() defaultValue = null isCrossinline = false isNoinline = false @@ -281,7 +283,7 @@ class FirCallCompleter( receiverType == null -> lambdaArgument.replaceReceiverParameter(null) !lambdaAtom.coerceFirstParameterToExtensionReceiver -> { lambdaArgument.receiverParameter?.apply { - val type = receiverType.approximateLambdaInputType() + val type = receiverType.approximateLambdaInputType(valueParameter = null) val source = source?.fakeElement(KtFakeSourceElementKind.ImplicitTypeRef) replaceTypeRef(typeRef.resolvedTypeFromPrototype(type, source)) } @@ -311,7 +313,7 @@ class FirCallCompleter( else -> parameters } lambdaArgument.valueParameters.forEachIndexed { index, parameter -> - val newReturnType = theParameters[index].approximateLambdaInputType() + val newReturnType = theParameters[index].approximateLambdaInputType(parameter.symbol) val newReturnTypeRef = if (parameter.returnTypeRef is FirImplicitTypeRef) { newReturnType.toFirResolvedTypeRef(parameter.source?.fakeElement(KtFakeSourceElementKind.ImplicitReturnTypeOfLambdaValueParameter)) } else parameter.returnTypeRef.resolvedTypeFromPrototype(newReturnType) @@ -352,10 +354,19 @@ class FirCallCompleter( } } - private fun ConeKotlinType.approximateLambdaInputType(): ConeKotlinType = - session.typeApproximator.approximateToSuperType( + private fun ConeKotlinType.approximateLambdaInputType(valueParameter: FirValueParameterSymbol?): ConeKotlinType { + // We only run lambda completion from ConstraintSystemCompletionContext.analyzeRemainingNotAnalyzedPostponedArgument when they are + // left uninferred. + // Currently, we use stub types for builder inference, so CANNOT_INFER_PARAMETER_TYPE is the only possible result here. + if (this is ConeTypeVariableType) { + val diagnostic = valueParameter?.let(::ConeCannotInferValueParameterType) ?: ConeCannotInferReceiverParameterType() + return ConeErrorType(diagnostic) + } + + return session.typeApproximator.approximateToSuperType( this, TypeApproximatorConfiguration.FinalApproximationAfterResolutionAndInference ) ?: this + } } private fun Candidate.isFunctionForExpectTypeFromCastFeature(): Boolean { 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 0414fd44404..77b22cf9e87 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 @@ -37,6 +37,10 @@ class ConeCannotInferValueParameterType( override val reason: String = "Cannot infer type for parameter ${valueParameter.name}" ) : ConeDiagnostic +class ConeCannotInferReceiverParameterType( + override val reason: String = "Cannot infer type for receiver parameter" +) : ConeDiagnostic + class ConeTypeVariableTypeIsNotInferred( val typeVariableType: ConeTypeVariableType, override val reason: String = "Type for ${typeVariableType.lookupTag.debugName} is not inferred" diff --git a/compiler/testData/diagnostics/tests/functionLiterals/kt47493.fir.kt b/compiler/testData/diagnostics/tests/functionLiterals/kt47493.fir.kt deleted file mode 100644 index 9e4a8bb82c8..00000000000 --- a/compiler/testData/diagnostics/tests/functionLiterals/kt47493.fir.kt +++ /dev/null @@ -1,24 +0,0 @@ -// IGNORE_LEAKED_INTERNAL_TYPES: KT-54568 -fun test1() { - try { - { toDouble -> - } - } catch (e: Exception) { - - } -} - -fun test2() { - try { - - } catch (e: Exception) { - { toDouble -> - } - } -} - -fun box(): String { - test1() - test2() - return "OK" -} diff --git a/compiler/testData/diagnostics/tests/functionLiterals/kt47493.kt b/compiler/testData/diagnostics/tests/functionLiterals/kt47493.kt index c771ffa3583..cfc87118e04 100644 --- a/compiler/testData/diagnostics/tests/functionLiterals/kt47493.kt +++ b/compiler/testData/diagnostics/tests/functionLiterals/kt47493.kt @@ -1,4 +1,4 @@ -// IGNORE_LEAKED_INTERNAL_TYPES: KT-54568 +// FIR_IDENTICAL fun test1() { try { { toDouble -> diff --git a/compiler/testData/diagnostics/tests/inference/completion/postponedArgumentsAnalysis/notInferableParameterOfAnonymousFunction.fir.kt b/compiler/testData/diagnostics/tests/inference/completion/postponedArgumentsAnalysis/notInferableParameterOfAnonymousFunction.fir.kt index 8531e9b4cdb..ec8755eebde 100644 --- a/compiler/testData/diagnostics/tests/inference/completion/postponedArgumentsAnalysis/notInferableParameterOfAnonymousFunction.fir.kt +++ b/compiler/testData/diagnostics/tests/inference/completion/postponedArgumentsAnalysis/notInferableParameterOfAnonymousFunction.fir.kt @@ -1,4 +1,3 @@ -// IGNORE_LEAKED_INTERNAL_TYPES: KT-54568 // !DIAGNOSTICS: -UNUSED_ANONYMOUS_PARAMETER -UNUSED_VARIABLE fun select(vararg x: T) = x[0] @@ -6,12 +5,12 @@ fun id(x: K) = x fun main() { val x1 = select(id { x, y -> }, { x: Int, y -> }) - val x2 = select(id { x, y -> }, { x: Int, y -> }) + val x2 = select(id { x, y -> }, { x: Int, y -> }) - val x3 = select(id(fun (x, y) {}), fun (x: Int, y) {}) + val x3 = select(id(fun (x, y) {}), fun (x: Int, y) {}) val x4 = select((fun (x, y) {}), fun (x: Int, y) {}) - val x5 = select(id(fun (x, y) {}), fun (x: Int, y) {}) + val x5 = select(id(fun (x, y) {}), fun (x: Int, y) {}) val x6 = id(fun (x) {}) select(fun (x) {}, fun (x) {}) diff --git a/compiler/testData/diagnostics/tests/inference/completion/postponedArgumentsAnalysis/notInferableParameterOfAnonymousFunction.kt b/compiler/testData/diagnostics/tests/inference/completion/postponedArgumentsAnalysis/notInferableParameterOfAnonymousFunction.kt index b525c0a82c2..0ba974cd9af 100644 --- a/compiler/testData/diagnostics/tests/inference/completion/postponedArgumentsAnalysis/notInferableParameterOfAnonymousFunction.kt +++ b/compiler/testData/diagnostics/tests/inference/completion/postponedArgumentsAnalysis/notInferableParameterOfAnonymousFunction.kt @@ -1,4 +1,3 @@ -// IGNORE_LEAKED_INTERNAL_TYPES: KT-54568 // !DIAGNOSTICS: -UNUSED_ANONYMOUS_PARAMETER -UNUSED_VARIABLE fun select(vararg x: T) = x[0] diff --git a/compiler/testData/diagnostics/tests/inference/nonFunctionalExpectedTypeForLambdaArgument.fir.kt b/compiler/testData/diagnostics/tests/inference/nonFunctionalExpectedTypeForLambdaArgument.fir.kt index 09f86b373c6..4a0a1e59823 100644 --- a/compiler/testData/diagnostics/tests/inference/nonFunctionalExpectedTypeForLambdaArgument.fir.kt +++ b/compiler/testData/diagnostics/tests/inference/nonFunctionalExpectedTypeForLambdaArgument.fir.kt @@ -1,4 +1,3 @@ -// IGNORE_LEAKED_INTERNAL_TYPES: KT-54568 // !DIAGNOSTICS: -UNUSED_PARAMETER fun callAny(arg: Any?) {} @@ -20,14 +19,14 @@ fun testAnyCall() { } fun testParam() { - callParam { - param -> param + callParam { + param -> param } } fun testParamCall() { callParam { - param -> param() + param -> param() } } diff --git a/compiler/testData/diagnostics/tests/inference/nonFunctionalExpectedTypeForLambdaArgument.kt b/compiler/testData/diagnostics/tests/inference/nonFunctionalExpectedTypeForLambdaArgument.kt index 10869fe484f..630d0a7a116 100644 --- a/compiler/testData/diagnostics/tests/inference/nonFunctionalExpectedTypeForLambdaArgument.kt +++ b/compiler/testData/diagnostics/tests/inference/nonFunctionalExpectedTypeForLambdaArgument.kt @@ -1,4 +1,3 @@ -// IGNORE_LEAKED_INTERNAL_TYPES: KT-54568 // !DIAGNOSTICS: -UNUSED_PARAMETER fun callAny(arg: Any?) {} diff --git a/compiler/testData/diagnostics/tests/inference/underscoredTypeInForbiddenPositions.fir.kt b/compiler/testData/diagnostics/tests/inference/underscoredTypeInForbiddenPositions.fir.kt index 4bd1452346e..1552b559c59 100644 --- a/compiler/testData/diagnostics/tests/inference/underscoredTypeInForbiddenPositions.fir.kt +++ b/compiler/testData/diagnostics/tests/inference/underscoredTypeInForbiddenPositions.fir.kt @@ -1,4 +1,3 @@ -// IGNORE_LEAKED_INTERNAL_TYPES: KT-54568 // !LANGUAGE: +PartiallySpecifiedTypeArguments // !DIAGNOSTICS: -UNCHECKED_CAST // WITH_STDLIB diff --git a/compiler/testData/diagnostics/tests/inference/underscoredTypeInForbiddenPositions.kt b/compiler/testData/diagnostics/tests/inference/underscoredTypeInForbiddenPositions.kt index 153eb3d4b21..a70dcfef95c 100644 --- a/compiler/testData/diagnostics/tests/inference/underscoredTypeInForbiddenPositions.kt +++ b/compiler/testData/diagnostics/tests/inference/underscoredTypeInForbiddenPositions.kt @@ -1,4 +1,3 @@ -// IGNORE_LEAKED_INTERNAL_TYPES: KT-54568 // !LANGUAGE: +PartiallySpecifiedTypeArguments // !DIAGNOSTICS: -UNCHECKED_CAST // WITH_STDLIB diff --git a/compiler/testData/diagnostics/tests/kt49438.fir.kt b/compiler/testData/diagnostics/tests/kt49438.fir.kt index e2cd65b37f7..113c45a9f6b 100644 --- a/compiler/testData/diagnostics/tests/kt49438.fir.kt +++ b/compiler/testData/diagnostics/tests/kt49438.fir.kt @@ -1,3 +1,7 @@ -// IGNORE_LEAKED_INTERNAL_TYPES: KT-54568 fun foo(x: K) {} -val x = foo<(unresolved) -> Float> { it.toFloat() } +val x1 = foo<(unresolved) -> Float> { it.toFloat() } +val x2 = foo<(unresolved) -> Float> { it -> it.toFloat() } +val x3 = foo<unresolved.() -> Float> { this.toFloat() } +val x4 = foo<(Array<unresolved>) -> Int> { it.size } + +fun bar() = foo<(T) -> String> { it.toString() } diff --git a/compiler/testData/diagnostics/tests/kt49438.kt b/compiler/testData/diagnostics/tests/kt49438.kt index 6b0c6468dde..2af24cd1cb7 100644 --- a/compiler/testData/diagnostics/tests/kt49438.kt +++ b/compiler/testData/diagnostics/tests/kt49438.kt @@ -1,3 +1,7 @@ -// IGNORE_LEAKED_INTERNAL_TYPES: KT-54568 fun foo(x: K) {} -val x = foo<(unresolved) -> Float> { it.toFloat() } +val x1 = foo<(unresolved) -> Float> { it.toFloat() } +val x2 = foo<(unresolved) -> Float> { it -> it.toFloat() } +val x3 = foo<unresolved.() -> Float> { this.toFloat() } +val x4 = foo<(Array<unresolved>) -> Int> { it.size } + +fun bar() = foo<(T) -> String> { it.toString() } diff --git a/compiler/testData/diagnostics/tests/kt49438.txt b/compiler/testData/diagnostics/tests/kt49438.txt index 6b52f887c58..423cc8dac6e 100644 --- a/compiler/testData/diagnostics/tests/kt49438.txt +++ b/compiler/testData/diagnostics/tests/kt49438.txt @@ -1,4 +1,8 @@ package -public val x: kotlin.Unit +public val x1: kotlin.Unit +public val x2: kotlin.Unit +public val x3: kotlin.Unit +public val x4: kotlin.Unit +public fun bar(): kotlin.Unit public fun foo(/*0*/ x: K): kotlin.Unit diff --git a/compiler/testData/diagnostics/tests/regressions/kt10843.fir.kt b/compiler/testData/diagnostics/tests/regressions/kt10843.fir.kt index 0452510818f..1c12ce604e4 100644 --- a/compiler/testData/diagnostics/tests/regressions/kt10843.fir.kt +++ b/compiler/testData/diagnostics/tests/regressions/kt10843.fir.kt @@ -1,8 +1,7 @@ -// IGNORE_LEAKED_INTERNAL_TYPES: KT-54568 // NI_EXPECTED_FILE // See EA-76890 / KT-10843: NPE during analysis fun lambda(x : Int?) = x?.let l { - y -> + y -> if (y > 0) return@l x y }!! diff --git a/compiler/testData/diagnostics/tests/regressions/kt10843.kt b/compiler/testData/diagnostics/tests/regressions/kt10843.kt index 50718c08ebb..50a313b667b 100644 --- a/compiler/testData/diagnostics/tests/regressions/kt10843.kt +++ b/compiler/testData/diagnostics/tests/regressions/kt10843.kt @@ -1,4 +1,3 @@ -// IGNORE_LEAKED_INTERNAL_TYPES: KT-54568 // NI_EXPECTED_FILE // See EA-76890 / KT-10843: NPE during analysis fun lambda(x : Int?) = x?.let l {