diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt index a95cdae7c4c..240e6f48deb 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt @@ -27,6 +27,7 @@ import org.jetbrains.kotlin.fir.resolve.calls.tower.FirTowerResolver import org.jetbrains.kotlin.fir.resolve.calls.tower.TowerGroup import org.jetbrains.kotlin.fir.resolve.calls.tower.TowerResolveManager import org.jetbrains.kotlin.fir.resolve.diagnostics.* +import org.jetbrains.kotlin.fir.resolve.inference.FirBuilderInferenceSession import org.jetbrains.kotlin.fir.resolve.inference.ResolvedCallableReferenceAtom import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor @@ -741,15 +742,20 @@ class FirCallResolver( ) } /* - * This `if` is an optimization for local variables and properties without type parameters + * This `if` is an optimization for local variables and properties without type parameters. * Since they have no type variables, so we can don't run completion on them at all and create - * resolved reference immediately + * resolved reference immediately. * - * But for callable reference resolution we should keep candidate, because it was resolved + * But for callable reference resolution (createResolvedReferenceWithoutCandidateForLocalVariables = true) + * we should keep candidate, because it was resolved * with special resolution stages, which saved in candidate additional reference info, - * like `resultingTypeForCallableReference` + * like `resultingTypeForCallableReference`. + * + * The same is true for builder inference session, because inference from expected type inside lambda + * can be important in builder inference mode, and it will never work if we skip completion here. + * See inferenceFromLambdaReturnStatement.kt test. */ - if ( + if (components.context.inferenceSession !is FirBuilderInferenceSession && createResolvedReferenceWithoutCandidateForLocalVariables && explicitReceiver?.typeRef?.coneTypeSafe() == null && coneSymbol is FirVariableSymbol && diff --git a/compiler/testData/diagnostics/testsWithStdLib/builderInference/inferenceFromLambdaReturnStatement.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/builderInference/inferenceFromLambdaReturnStatement.fir.kt deleted file mode 100644 index 5a369214890..00000000000 --- a/compiler/testData/diagnostics/testsWithStdLib/builderInference/inferenceFromLambdaReturnStatement.fir.kt +++ /dev/null @@ -1,10 +0,0 @@ -// ISSUE: KT-57889 - -class SafeResult - -inline fun checkNotEdt(body: (SafeResult) -> Nothing) {} - -private fun getNonEdt(): SafeResult { - checkNotEdt { return it } - return SafeResult() -} diff --git a/compiler/testData/diagnostics/testsWithStdLib/builderInference/inferenceFromLambdaReturnStatement.kt b/compiler/testData/diagnostics/testsWithStdLib/builderInference/inferenceFromLambdaReturnStatement.kt index b92c4af882d..4d84c4aba29 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/builderInference/inferenceFromLambdaReturnStatement.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/builderInference/inferenceFromLambdaReturnStatement.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // ISSUE: KT-57889 class SafeResult diff --git a/compiler/testData/diagnostics/testsWithStdLib/builderInference/unsafeAssignment.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/builderInference/unsafeAssignment.fir.kt index 9c9af6b6873..50c554a0aeb 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/builderInference/unsafeAssignment.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/builderInference/unsafeAssignment.fir.kt @@ -9,16 +9,16 @@ fun main(arg: Any) { val x = 57 val value = myBuilder { doSmthng("one ") - run { a; this }.a = 10 + run { a; this }.a = 10 a += 1 - this.a = 57 + this.a = 57 this.(a) = 57 - a = x - (a) = x + a = x + (a) = x a.hashCode = 99 if (arg is String) { a = arg } } - println(value.a?.count { it in 'l' .. 'q' }) + println(value.a?.count { it in 'l' .. 'q' }) } diff --git a/compiler/testData/diagnostics/testsWithStdLib/builderInference/unsafeAssignment_noReport.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/builderInference/unsafeAssignment_noReport.fir.kt index 8d3e441103a..a7e1e2c30ec 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/builderInference/unsafeAssignment_noReport.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/builderInference/unsafeAssignment_noReport.fir.kt @@ -1,4 +1,5 @@ // !LANGUAGE: +NoBuilderInferenceWithoutAnnotationRestriction +// FIR_DUMP class Foo { fun doSmthng(arg: T) {} @@ -11,11 +12,11 @@ fun main(arg: Any) { val x = 57 val value = myBuilder { doSmthng("one ") - a = 57 - a = x + a = 57 + a = x if (arg is String) { a = arg } } - println(value.a?.count { it in 'l' .. 'q' }) + println(value.a?.count { it in 'l' .. 'q' }) } diff --git a/compiler/testData/diagnostics/testsWithStdLib/builderInference/unsafeAssignment_noReport.fir.txt b/compiler/testData/diagnostics/testsWithStdLib/builderInference/unsafeAssignment_noReport.fir.txt new file mode 100644 index 00000000000..a10aa789b19 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/builderInference/unsafeAssignment_noReport.fir.txt @@ -0,0 +1,36 @@ +FILE: unsafeAssignment_noReport.fir.kt + public final class Foo : R|kotlin/Any| { + public constructor(): R|Foo| { + super() + } + + public final fun doSmthng(arg: R|T|): R|kotlin/Unit| { + } + + public final var a: R|T?| = Null(null) + public get(): R|T?| + public set(value: R|T?|): R|kotlin/Unit| + + } + public final fun myBuilder(block: R|Foo.() -> kotlin/Unit|): R|Foo| { + ^myBuilder R|/Foo.Foo|().R|kotlin/apply||>(R|/block|) + } + public final fun main(arg: R|kotlin/Any|): R|kotlin/Unit| { + lval x: R|kotlin/Int| = Int(57) + lval value: R|Foo| = R|/myBuilder|( = myBuilder@fun R|Foo|.(): R|kotlin/Unit| { + this@R|special/anonymous|.R|SubstitutionOverride|(String(one )) + this@R|special/anonymous|.R|SubstitutionOverride| = Int(57) + this@R|special/anonymous|.R|SubstitutionOverride| = R|/x| + when () { + (R|/arg| is R|kotlin/String|) -> { + this@R|special/anonymous|.R|SubstitutionOverride| = R|/arg| + } + } + + } + ) + #(R|/value|.R|SubstitutionOverride|?.{ $subj$.#( = count@fun (): R|kotlin/Boolean| { + ^ Char(l).R|kotlin/Char.rangeTo|(Char(q)).R|kotlin/ranges/CharRange.contains|(#) + } + ) }) + } diff --git a/compiler/testData/diagnostics/testsWithStdLib/builderInference/unsafeAssignment_noReport.kt b/compiler/testData/diagnostics/testsWithStdLib/builderInference/unsafeAssignment_noReport.kt index 78d6520f9b5..99b058ff9d1 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/builderInference/unsafeAssignment_noReport.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/builderInference/unsafeAssignment_noReport.kt @@ -1,4 +1,5 @@ // !LANGUAGE: +NoBuilderInferenceWithoutAnnotationRestriction +// FIR_DUMP class Foo { fun doSmthng(arg: T) {}