From e359db411147ea9c5f51483c1e57eae72de953ab Mon Sep 17 00:00:00 2001 From: "Denis.Zharkov" Date: Wed, 10 Jan 2024 17:19:35 +0100 Subject: [PATCH] K2: Set proper source for implicit `it`/receiver parameter Previously, error types on those implicit parameters were being lost. Changed test data is only partly here (only parts that are considered to be correct). Other ones (new green-to-red changes) should belong to the next commit and will be fixed soon (as a part of PCLA). --- .../fir/resolve/inference/FirCallCompleter.kt | 9 +++++-- .../org/jetbrains/kotlin/KtSourceElement.kt | 3 +++ .../output.txt | 4 ++++ .../builderInference/issues/kt49263.fir.kt | 4 ++-- .../ea81649_errorPropertyLHS.fir.kt | 4 ++-- ...nnotationInLambdaWithTVExpectedType.fir.kt | 4 ++-- .../stubTypeReceiverRestriction.fir.kt | 24 +++++++++---------- ...stubTypeReceiverRestrictionDisabled.fir.kt | 24 +++++++++---------- .../postponedArgumentsAnalysis/basic.fir.kt | 10 ++++---- .../inference/functionPlaceholderError.fir.kt | 16 +++++++++++++ .../inference/functionPlaceholderError.kt | 1 - .../diagnostics/tests/inference/kt6175.fir.kt | 10 ++++---- .../tests/inference/regressions/kt2445.fir.kt | 11 +++++++++ .../tests/inference/regressions/kt2445.kt | 1 - .../FunctionPlaceholder.fir.kt | 2 +- ...underscoredTypeInForbiddenPositions.fir.kt | 4 ++-- .../testData/diagnostics/tests/kt49438.fir.kt | 4 ++-- .../primaryConstructorParameter.fir.kt | 2 +- .../tests/regressions/kt1489_1728.fir.kt | 4 ++-- .../tests/regressions/kt31975.fir.kt | 2 +- .../typeVariableShouldNotBeFixed.fir.kt | 4 ++-- .../inference/stubCallOnReceiver.fir.kt | 4 ++-- 22 files changed, 94 insertions(+), 57 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/inference/functionPlaceholderError.fir.kt create mode 100644 compiler/testData/diagnostics/tests/inference/regressions/kt2445.fir.kt 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 5b8384f1401..bdf2985b690 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 @@ -266,7 +266,10 @@ class FirCallCompleter( origin = FirDeclarationOrigin.Source this.name = name symbol = FirValueParameterSymbol(name) - returnTypeRef = itType.approximateLambdaInputType(symbol).toFirResolvedTypeRef() + returnTypeRef = + itType.approximateLambdaInputType(symbol).toFirResolvedTypeRef( + lambdaAtom.atom.source?.fakeElement(KtFakeSourceElementKind.ItLambdaParameter) + ) defaultValue = null isCrossinline = false isNoinline = false @@ -283,7 +286,9 @@ class FirCallCompleter( !lambdaAtom.coerceFirstParameterToExtensionReceiver -> { lambdaArgument.receiverParameter?.apply { val type = receiverType.approximateLambdaInputType(valueParameter = null) - val source = source?.fakeElement(KtFakeSourceElementKind.ImplicitTypeRef) + val source = + source?.fakeElement(KtFakeSourceElementKind.LambdaReceiver) + ?: lambdaArgument.source?.fakeElement(KtFakeSourceElementKind.LambdaReceiver) replaceTypeRef(typeRef.resolvedTypeFromPrototype(type, source)) } } diff --git a/compiler/frontend.common/src/org/jetbrains/kotlin/KtSourceElement.kt b/compiler/frontend.common/src/org/jetbrains/kotlin/KtSourceElement.kt index 591540b1427..0a437e643e5 100644 --- a/compiler/frontend.common/src/org/jetbrains/kotlin/KtSourceElement.kt +++ b/compiler/frontend.common/src/org/jetbrains/kotlin/KtSourceElement.kt @@ -230,6 +230,9 @@ sealed class KtFakeSourceElementKind(final override val shouldSkipErrorTypeRepor // where `it` parameter declaration has fake source object ItLambdaParameter : KtFakeSourceElementKind() + // While it doesn't have an explicit source, it still has a type that might be a ConeErrorType + object LambdaReceiver : KtFakeSourceElementKind() + // { (a, b) -> foo() } -> { x -> val (a, b) = x; { foo() } } // where the inner block { foo() } has fake source object LambdaDestructuringBlock : KtFakeSourceElementKind() diff --git a/compiler/testData/compileKotlinAgainstCustomBinaries/strictMetadataVersionSemanticsOldVersion/output.txt b/compiler/testData/compileKotlinAgainstCustomBinaries/strictMetadataVersionSemanticsOldVersion/output.txt index a373986bb53..bc9a9a9b703 100644 --- a/compiler/testData/compileKotlinAgainstCustomBinaries/strictMetadataVersionSemanticsOldVersion/output.txt +++ b/compiler/testData/compileKotlinAgainstCustomBinaries/strictMetadataVersionSemanticsOldVersion/output.txt @@ -14,6 +14,10 @@ compiler/testData/compileKotlinAgainstCustomBinaries/strictMetadataVersionSemant The class is loaded from $TMP_DIR$/library.jar!/a/C.class c.let { C() } ^ +compiler/testData/compileKotlinAgainstCustomBinaries/strictMetadataVersionSemanticsOldVersion/source.kt:6:11: error: class 'a.C' was compiled with an incompatible version of Kotlin. The actual metadata version is $ABI_VERSION_NEXT$, but the compiler version $ABI_VERSION$ can read versions up to $ABI_VERSION$. +The class is loaded from $TMP_DIR$/library.jar!/a/C.class + c.let { C() } + ^ compiler/testData/compileKotlinAgainstCustomBinaries/strictMetadataVersionSemanticsOldVersion/source.kt:6:13: error: class 'a.C' was compiled with an incompatible version of Kotlin. The actual metadata version is $ABI_VERSION_NEXT$, but the compiler version $ABI_VERSION$ can read versions up to $ABI_VERSION$. The class is loaded from $TMP_DIR$/library.jar!/a/C.class c.let { C() } diff --git a/compiler/testData/diagnostics/tests/builderInference/issues/kt49263.fir.kt b/compiler/testData/diagnostics/tests/builderInference/issues/kt49263.fir.kt index db8006a6d86..676cfeed9bf 100644 --- a/compiler/testData/diagnostics/tests/builderInference/issues/kt49263.fir.kt +++ b/compiler/testData/diagnostics/tests/builderInference/issues/kt49263.fir.kt @@ -2,9 +2,9 @@ // CHECK_TYPE_WITH_EXACT fun test() { - val targetType = buildPostponedTypeVariable { + val targetType = buildPostponedTypeVariable { consumeTargetType(this) - } + } // exact type equality check — turns unexpected compile-time behavior into red code // considered to be non-user-reproducible code for the purposes of these tests checkExactType(targetType) diff --git a/compiler/testData/diagnostics/tests/callableReference/ea81649_errorPropertyLHS.fir.kt b/compiler/testData/diagnostics/tests/callableReference/ea81649_errorPropertyLHS.fir.kt index 83bc5593295..33860afa466 100644 --- a/compiler/testData/diagnostics/tests/callableReference/ea81649_errorPropertyLHS.fir.kt +++ b/compiler/testData/diagnostics/tests/callableReference/ea81649_errorPropertyLHS.fir.kt @@ -14,7 +14,7 @@ fun bar(ff: Err.() -> Unit) { data class User(val surname: String) fun foo() { - bar { + bar { User::surname - } + } } diff --git a/compiler/testData/diagnostics/tests/inference/builderInference/builderInferenceAnnotationInLambdaWithTVExpectedType.fir.kt b/compiler/testData/diagnostics/tests/inference/builderInference/builderInferenceAnnotationInLambdaWithTVExpectedType.fir.kt index 9adc37f0f39..fd5e0c080e4 100644 --- a/compiler/testData/diagnostics/tests/inference/builderInference/builderInferenceAnnotationInLambdaWithTVExpectedType.fir.kt +++ b/compiler/testData/diagnostics/tests/inference/builderInference/builderInferenceAnnotationInLambdaWithTVExpectedType.fir.kt @@ -9,7 +9,7 @@ fun applyBI(@BuilderInference t: T): T = t fun myBuildList(a: MutableList.() -> Unit) {} fun main() { - myBuildList(applyBI { + myBuildList(applyBI { this.add("1") - }) + }) } diff --git a/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/stubTypeReceiverRestriction.fir.kt b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/stubTypeReceiverRestriction.fir.kt index 34f385d81a6..da7153484b7 100644 --- a/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/stubTypeReceiverRestriction.fir.kt +++ b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/stubTypeReceiverRestriction.fir.kt @@ -8,31 +8,31 @@ fun T.extension() {} fun use(p: Any?) {} fun test1() { - a { + a { this.get(0).extension() use(this.get(0)::extension) use(it::extension) - } + } } fun test2() { - a { + a { val v = this.get(0) v.extension() use(v::extension) use(it::extension) - } + } } fun test3() { operator fun T.getValue(thisRef: Any?, prop: Any?): T = this - a { + a { val v by this.get(0) v.extension() use(v::extension) use(it::extension) - } + } } class Box(val t: TIn) @@ -40,12 +40,12 @@ class Box(val t: TIn) fun test4() { operator fun T.provideDelegate(thisRef: Any?, prop: Any?): Box = Box(this) operator fun Box.getValue(thisRef: Any?, prop: Any?): T = this.t - a { + a { val v by this.get(0) v.extension() use(v::extension) use(it::extension) - } + } } fun b(lambda: R.(List) -> Unit) {} @@ -53,20 +53,20 @@ fun b(lambda: R.(List) -> Unit) {} fun test5() { operator fun T.invoke(): T = this - b { + b { extension() this().extension() use(::extension) - } + } } val T.genericLambda: T.((T) -> Unit) -> Unit get() = {} fun test6() { - b { + b { extension() genericLambda { } genericLambda { it.extension() } use(::extension) - } + } } diff --git a/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/stubTypeReceiverRestrictionDisabled.fir.kt b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/stubTypeReceiverRestrictionDisabled.fir.kt index 6e53c868631..3263834cbf7 100644 --- a/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/stubTypeReceiverRestrictionDisabled.fir.kt +++ b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/stubTypeReceiverRestrictionDisabled.fir.kt @@ -9,31 +9,31 @@ fun T.extension() {} fun use(p: Any?) {} fun test1() { - a { + a { this.get(0).extension() use(this.get(0)::extension) use(it::extension) - } + } } fun test2() { - a { + a { val v = this.get(0) v.extension() use(v::extension) use(it::extension) - } + } } fun test3() { operator fun T.getValue(thisRef: Any?, prop: Any?): T = this - a { + a { val v by this.get(0) v.extension() use(v::extension) use(it::extension) - } + } } class Box(val t: TIn) @@ -41,12 +41,12 @@ class Box(val t: TIn) fun test4() { operator fun T.provideDelegate(thisRef: Any?, prop: Any?): Box = Box(this) operator fun Box.getValue(thisRef: Any?, prop: Any?): T = this.t - a { + a { val v by this.get(0) v.extension() use(v::extension) use(it::extension) - } + } } fun b(lambda: R.(List) -> Unit) {} @@ -54,20 +54,20 @@ fun b(lambda: R.(List) -> Unit) {} fun test5() { operator fun T.invoke(): T = this - b { + b { extension() this().extension() use(::extension) - } + } } val T.genericLambda: T.((T) -> Unit) -> Unit get() = {} fun test6() { - b { + b { extension() genericLambda { } genericLambda { it.extension() } use(::extension) - } + } } diff --git a/compiler/testData/diagnostics/tests/inference/completion/postponedArgumentsAnalysis/basic.fir.kt b/compiler/testData/diagnostics/tests/inference/completion/postponedArgumentsAnalysis/basic.fir.kt index eda4fcd1b63..c292016c533 100644 --- a/compiler/testData/diagnostics/tests/inference/completion/postponedArgumentsAnalysis/basic.fir.kt +++ b/compiler/testData/diagnostics/tests/inference/completion/postponedArgumentsAnalysis/basic.fir.kt @@ -78,11 +78,11 @@ fun main() { // Interdependent lambdas by input-output types aren't supported takeInterdependentLambdas({}, {}) - takeInterdependentLambdas({ it }, { 10 }) - takeInterdependentLambdas({ 10 }, { it }) - takeInterdependentLambdas({ 10 }, { x -> x }) - takeInterdependentLambdas({ x -> 10 }, { it }) - takeInterdependentLambdas({ it }, { x -> 10 }) + takeInterdependentLambdas({ it }, { 10 }) + takeInterdependentLambdas({ 10 }, { it }) + takeInterdependentLambdas({ 10 }, { x -> x }) + takeInterdependentLambdas({ x -> 10 }, { it }) + takeInterdependentLambdas({ it }, { x -> 10 }) // Dependent lambdas by input-output types takeDependentLambdas({ it }, { it }) diff --git a/compiler/testData/diagnostics/tests/inference/functionPlaceholderError.fir.kt b/compiler/testData/diagnostics/tests/inference/functionPlaceholderError.fir.kt new file mode 100644 index 00000000000..21e87e0a71b --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/functionPlaceholderError.fir.kt @@ -0,0 +1,16 @@ +// !CHECK_TYPE + +package a + +import checkSubtype + +fun emptyList(): List = throw Exception() + +fun foo(f: T.() -> Unit, l: List): T = throw Exception("$f$l") + +fun test() { + val q = foo(fun Int.() {}, emptyList()) //type inference no information for parameter error + checkSubtype(q) + + foo({}, emptyList()) +} diff --git a/compiler/testData/diagnostics/tests/inference/functionPlaceholderError.kt b/compiler/testData/diagnostics/tests/inference/functionPlaceholderError.kt index a01587105fb..338c1397a81 100644 --- a/compiler/testData/diagnostics/tests/inference/functionPlaceholderError.kt +++ b/compiler/testData/diagnostics/tests/inference/functionPlaceholderError.kt @@ -1,4 +1,3 @@ -// FIR_IDENTICAL // !CHECK_TYPE package a diff --git a/compiler/testData/diagnostics/tests/inference/kt6175.fir.kt b/compiler/testData/diagnostics/tests/inference/kt6175.fir.kt index 2ff9aa3de41..ab125ae4b21 100644 --- a/compiler/testData/diagnostics/tests/inference/kt6175.fir.kt +++ b/compiler/testData/diagnostics/tests/inference/kt6175.fir.kt @@ -3,9 +3,9 @@ fun foo(body: (R?) -> T): T = fail() fun test1() { - foo { + foo { true - } + } foo { x -> true } @@ -15,9 +15,9 @@ fun test1() { fun bar(body: (R) -> T): T = fail() fun test2() { - bar { + bar { true - } + } bar { x -> true } @@ -45,4 +45,4 @@ fun test4() { } } -fun fail(): Nothing = throw Exception() \ No newline at end of file +fun fail(): Nothing = throw Exception() diff --git a/compiler/testData/diagnostics/tests/inference/regressions/kt2445.fir.kt b/compiler/testData/diagnostics/tests/inference/regressions/kt2445.fir.kt new file mode 100644 index 00000000000..b06ac522803 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/regressions/kt2445.fir.kt @@ -0,0 +1,11 @@ +// !DIAGNOSTICS: -UNREACHABLE_CODE +//KT-2445 Calling method with function with generic parameter causes compile-time exception +package a + +fun main() { + test { + + } +} + +fun test(callback: (R) -> Unit):Unit = callback(null!!) diff --git a/compiler/testData/diagnostics/tests/inference/regressions/kt2445.kt b/compiler/testData/diagnostics/tests/inference/regressions/kt2445.kt index ca971fad4a1..94def98c406 100644 --- a/compiler/testData/diagnostics/tests/inference/regressions/kt2445.kt +++ b/compiler/testData/diagnostics/tests/inference/regressions/kt2445.kt @@ -1,4 +1,3 @@ -// FIR_IDENTICAL // !DIAGNOSTICS: -UNREACHABLE_CODE //KT-2445 Calling method with function with generic parameter causes compile-time exception package a diff --git a/compiler/testData/diagnostics/tests/inference/reportingImprovements/FunctionPlaceholder.fir.kt b/compiler/testData/diagnostics/tests/inference/reportingImprovements/FunctionPlaceholder.fir.kt index 8ca23055289..82e60c60f65 100644 --- a/compiler/testData/diagnostics/tests/inference/reportingImprovements/FunctionPlaceholder.fir.kt +++ b/compiler/testData/diagnostics/tests/inference/reportingImprovements/FunctionPlaceholder.fir.kt @@ -10,7 +10,7 @@ fun test() { foo { x -> x} foo { x: Int -> x} - bar { it + 1 } + bar { it + 1 } bar { x -> x + 1} bar { x: Int -> x + 1} } diff --git a/compiler/testData/diagnostics/tests/inference/underscoredTypeInForbiddenPositions.fir.kt b/compiler/testData/diagnostics/tests/inference/underscoredTypeInForbiddenPositions.fir.kt index 12a135acb3e..ea1e01f5870 100644 --- a/compiler/testData/diagnostics/tests/inference/underscoredTypeInForbiddenPositions.fir.kt +++ b/compiler/testData/diagnostics/tests/inference/underscoredTypeInForbiddenPositions.fir.kt @@ -42,9 +42,9 @@ fun <`_`> bar(): Foo<_> = TODO() fun <`_`> bar1(): Foo_>> = TODO() fun test() { - val x1 = foo_) -> Unit> { { it } } + val x1 = foo_) -> Unit> { { it } } val x2 = foo _> { { it } } - val x3 = foo_)) -> _> { { it } } + val x3 = foo_)) -> _> { { it } } val x4 = foo<Int, _ -> Float> { { it } } val x5 = foo_) -> Float>> { { it } } val x6 = foo_) -> _>> { { it } } diff --git a/compiler/testData/diagnostics/tests/kt49438.fir.kt b/compiler/testData/diagnostics/tests/kt49438.fir.kt index 4702376d00f..27b48ac090e 100644 --- a/compiler/testData/diagnostics/tests/kt49438.fir.kt +++ b/compiler/testData/diagnostics/tests/kt49438.fir.kt @@ -1,7 +1,7 @@ fun foo(x: K) {} -val x1 = 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 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/properties/inferenceFromGetters/primaryConstructorParameter.fir.kt b/compiler/testData/diagnostics/tests/properties/inferenceFromGetters/primaryConstructorParameter.fir.kt index c4b805a4436..f7fc98c65d5 100644 --- a/compiler/testData/diagnostics/tests/properties/inferenceFromGetters/primaryConstructorParameter.fir.kt +++ b/compiler/testData/diagnostics/tests/properties/inferenceFromGetters/primaryConstructorParameter.fir.kt @@ -19,7 +19,7 @@ class C(p: Any, val v: Any) { var test5 get() { return p } - set(nv) { p.let {} } + set(nv) { p.let {} } lateinit var test6 } diff --git a/compiler/testData/diagnostics/tests/regressions/kt1489_1728.fir.kt b/compiler/testData/diagnostics/tests/regressions/kt1489_1728.fir.kt index ad47b7a20ed..12ce02689d5 100644 --- a/compiler/testData/diagnostics/tests/regressions/kt1489_1728.fir.kt +++ b/compiler/testData/diagnostics/tests/regressions/kt1489_1728.fir.kt @@ -18,9 +18,9 @@ class C { fun p() : Resource? = null fun bar() { - foo(p()) { + foo(p()) { - } + } } } diff --git a/compiler/testData/diagnostics/tests/regressions/kt31975.fir.kt b/compiler/testData/diagnostics/tests/regressions/kt31975.fir.kt index 3b3417e6f01..c758d695235 100644 --- a/compiler/testData/diagnostics/tests/regressions/kt31975.fir.kt +++ b/compiler/testData/diagnostics/tests/regressions/kt31975.fir.kt @@ -9,7 +9,7 @@ interface A interface TypeConstructor class Refiner { - val memoizedFunctionLambda = createMemoizedFunction { it.foo() } // error type infered, no diagnostic, BAD, backend fails + val memoizedFunctionLambda = createMemoizedFunction { it.foo() } // error type infered, no diagnostic, BAD, backend fails val memoizedFunctionReference = createMemoizedFunction(TypeConstructor::foo) // EXTENSION_IN_CLASS_REFERENCE_IS_NOT_ALLOWED, fine val memoizedFunctionTypes = createMemoizedFunction { it.foo() } // works fine diff --git a/compiler/testData/diagnostics/testsWithStdLib/builderInference/typeVariableShouldNotBeFixed.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/builderInference/typeVariableShouldNotBeFixed.fir.kt index 3556c030def..4f5bf15da3b 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/builderInference/typeVariableShouldNotBeFixed.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/builderInference/typeVariableShouldNotBeFixed.fir.kt @@ -23,10 +23,10 @@ fun context(p: Processor, exec: Exec) {} fun materialize(): Processor = TODO() private fun foo(model: Model) { - materialize().apply { + materialize().apply { context( this, Exec { m, p -> p.process(m) } // Note: Builder inference ) - } + } } diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/stubCallOnReceiver.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/stubCallOnReceiver.fir.kt index c6aa3448ec8..c248b9f22d6 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/stubCallOnReceiver.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/stubCallOnReceiver.fir.kt @@ -12,13 +12,13 @@ fun defineType(definition: TypeDefinition.() -> U fun foo() { defineType { parse { it.toInt() } - serialize { toString() } + serialize { toString() } } } fun bar() { defineType { parse { it.toInt() } - serialize { this.toString() } + serialize { this.toString() } } }