FirCallResolve: disable property resolve optimization in builder inference
#KT-57889 Fixed
This commit is contained in:
committed by
Space Team
parent
f9a7a7fda2
commit
9374202ebc
@@ -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<ConeIntegerLiteralType>() == null &&
|
||||
coneSymbol is FirVariableSymbol &&
|
||||
|
||||
-10
@@ -1,10 +0,0 @@
|
||||
// ISSUE: KT-57889
|
||||
|
||||
class SafeResult<S>
|
||||
|
||||
inline fun <T> checkNotEdt(body: (SafeResult<T>) -> Nothing) {}
|
||||
|
||||
private fun <V> getNonEdt(): SafeResult<V> {
|
||||
<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>checkNotEdt<!> { return it }
|
||||
return SafeResult()
|
||||
}
|
||||
compiler/testData/diagnostics/testsWithStdLib/builderInference/inferenceFromLambdaReturnStatement.kt
Vendored
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// ISSUE: KT-57889
|
||||
|
||||
class SafeResult<S>
|
||||
|
||||
+5
-5
@@ -9,16 +9,16 @@ fun main(arg: Any) {
|
||||
val x = 57
|
||||
val value = myBuilder {
|
||||
doSmthng("one ")
|
||||
run { a; this }.a = <!ASSIGNMENT_TYPE_MISMATCH!>10<!>
|
||||
run { a; this }.a = 10
|
||||
a += 1
|
||||
this.a = <!ASSIGNMENT_TYPE_MISMATCH!>57<!>
|
||||
this.a = 57
|
||||
this.<!ILLEGAL_SELECTOR, VARIABLE_EXPECTED!>(a)<!> = 57
|
||||
a = <!ASSIGNMENT_TYPE_MISMATCH!>x<!>
|
||||
(a) = <!ASSIGNMENT_TYPE_MISMATCH!>x<!>
|
||||
a = x
|
||||
(a) = x
|
||||
a.<!FUNCTION_CALL_EXPECTED, VARIABLE_EXPECTED!>hashCode<!> = 99
|
||||
if (arg is String) {
|
||||
a = arg
|
||||
}
|
||||
}
|
||||
println(value.a?.count { it in 'l' .. 'q' })
|
||||
<!OVERLOAD_RESOLUTION_AMBIGUITY!>println<!>(value.a?.<!UNRESOLVED_REFERENCE!>count<!> { <!UNRESOLVED_REFERENCE!>it<!> in 'l' .. 'q' })
|
||||
}
|
||||
|
||||
Vendored
+4
-3
@@ -1,4 +1,5 @@
|
||||
// !LANGUAGE: +NoBuilderInferenceWithoutAnnotationRestriction
|
||||
// FIR_DUMP
|
||||
|
||||
class Foo<T : Any> {
|
||||
fun doSmthng(arg: T) {}
|
||||
@@ -11,11 +12,11 @@ fun main(arg: Any) {
|
||||
val x = 57
|
||||
val value = myBuilder {
|
||||
doSmthng("one ")
|
||||
a = <!ASSIGNMENT_TYPE_MISMATCH!>57<!>
|
||||
a = <!ASSIGNMENT_TYPE_MISMATCH!>x<!>
|
||||
a = 57
|
||||
a = x
|
||||
if (arg is String) {
|
||||
a = arg
|
||||
}
|
||||
}
|
||||
println(value.a?.count { it in 'l' .. 'q' })
|
||||
<!OVERLOAD_RESOLUTION_AMBIGUITY!>println<!>(value.a?.<!UNRESOLVED_REFERENCE!>count<!> { <!UNRESOLVED_REFERENCE!>it<!> in 'l' .. 'q' })
|
||||
}
|
||||
|
||||
Vendored
+36
@@ -0,0 +1,36 @@
|
||||
FILE: unsafeAssignment_noReport.fir.kt
|
||||
public final class Foo<T : R|kotlin/Any|> : R|kotlin/Any| {
|
||||
public constructor<T : R|kotlin/Any|>(): R|Foo<T>| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
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 <T : R|kotlin/Any|> myBuilder(block: R|Foo<T>.() -> kotlin/Unit|): R|Foo<T>| {
|
||||
^myBuilder R|/Foo.Foo|<R|T|>().R|kotlin/apply|<R|Foo<T>|>(R|<local>/block|)
|
||||
}
|
||||
public final fun main(arg: R|kotlin/Any|): R|kotlin/Unit| {
|
||||
lval x: R|kotlin/Int| = Int(57)
|
||||
lval value: R|Foo<kotlin/Any>| = R|/myBuilder|<R|kotlin/Any|>(<L> = myBuilder@fun R|Foo<kotlin/Any>|.<anonymous>(): R|kotlin/Unit| <inline=NoInline> {
|
||||
this@R|special/anonymous|.R|SubstitutionOverride</Foo.doSmthng: R|kotlin/Unit|>|(String(one ))
|
||||
this@R|special/anonymous|.R|SubstitutionOverride</Foo.a: R|Stub (chain inference): TypeVariable(T)?|>| = Int(57)
|
||||
this@R|special/anonymous|.R|SubstitutionOverride</Foo.a: R|Stub (chain inference): TypeVariable(T)?|>| = R|<local>/x|
|
||||
when () {
|
||||
(R|<local>/arg| is R|kotlin/String|) -> {
|
||||
this@R|special/anonymous|.R|SubstitutionOverride</Foo.a: R|Stub (chain inference): TypeVariable(T)?|>| = R|<local>/arg|
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
)
|
||||
<Ambiguity: println, [kotlin/io/println, kotlin/io/println, kotlin/io/println, kotlin/io/println, kotlin/io/println, kotlin/io/println, kotlin/io/println, kotlin/io/println, kotlin/io/println, kotlin/io/println]>#(R|<local>/value|.R|SubstitutionOverride</Foo.a: R|kotlin/Any?|>|?.{ $subj$.<Unresolved name: count>#(<L> = count@fun <anonymous>(): R|kotlin/Boolean| <inline=Unknown> {
|
||||
^ Char(l).R|kotlin/Char.rangeTo|(Char(q)).R|kotlin/ranges/CharRange.contains|(<Unresolved name: it>#)
|
||||
}
|
||||
) })
|
||||
}
|
||||
Vendored
+1
@@ -1,4 +1,5 @@
|
||||
// !LANGUAGE: +NoBuilderInferenceWithoutAnnotationRestriction
|
||||
// FIR_DUMP
|
||||
|
||||
class Foo<T : Any> {
|
||||
fun doSmthng(arg: T) {}
|
||||
|
||||
Reference in New Issue
Block a user