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.TowerGroup
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.tower.TowerResolveManager
|
import org.jetbrains.kotlin.fir.resolve.calls.tower.TowerResolveManager
|
||||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.*
|
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.ResolvedCallableReferenceAtom
|
||||||
import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents
|
import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
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
|
* 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,
|
* 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 &&
|
createResolvedReferenceWithoutCandidateForLocalVariables &&
|
||||||
explicitReceiver?.typeRef?.coneTypeSafe<ConeIntegerLiteralType>() == null &&
|
explicitReceiver?.typeRef?.coneTypeSafe<ConeIntegerLiteralType>() == null &&
|
||||||
coneSymbol is FirVariableSymbol &&
|
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
|
// ISSUE: KT-57889
|
||||||
|
|
||||||
class SafeResult<S>
|
class SafeResult<S>
|
||||||
|
|||||||
+5
-5
@@ -9,16 +9,16 @@ fun main(arg: Any) {
|
|||||||
val x = 57
|
val x = 57
|
||||||
val value = myBuilder {
|
val value = myBuilder {
|
||||||
doSmthng("one ")
|
doSmthng("one ")
|
||||||
run { a; this }.a = <!ASSIGNMENT_TYPE_MISMATCH!>10<!>
|
run { a; this }.a = 10
|
||||||
a += 1
|
a += 1
|
||||||
this.a = <!ASSIGNMENT_TYPE_MISMATCH!>57<!>
|
this.a = 57
|
||||||
this.<!ILLEGAL_SELECTOR, VARIABLE_EXPECTED!>(a)<!> = 57
|
this.<!ILLEGAL_SELECTOR, VARIABLE_EXPECTED!>(a)<!> = 57
|
||||||
a = <!ASSIGNMENT_TYPE_MISMATCH!>x<!>
|
a = x
|
||||||
(a) = <!ASSIGNMENT_TYPE_MISMATCH!>x<!>
|
(a) = x
|
||||||
a.<!FUNCTION_CALL_EXPECTED, VARIABLE_EXPECTED!>hashCode<!> = 99
|
a.<!FUNCTION_CALL_EXPECTED, VARIABLE_EXPECTED!>hashCode<!> = 99
|
||||||
if (arg is String) {
|
if (arg is String) {
|
||||||
a = arg
|
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
|
// !LANGUAGE: +NoBuilderInferenceWithoutAnnotationRestriction
|
||||||
|
// FIR_DUMP
|
||||||
|
|
||||||
class Foo<T : Any> {
|
class Foo<T : Any> {
|
||||||
fun doSmthng(arg: T) {}
|
fun doSmthng(arg: T) {}
|
||||||
@@ -11,11 +12,11 @@ fun main(arg: Any) {
|
|||||||
val x = 57
|
val x = 57
|
||||||
val value = myBuilder {
|
val value = myBuilder {
|
||||||
doSmthng("one ")
|
doSmthng("one ")
|
||||||
a = <!ASSIGNMENT_TYPE_MISMATCH!>57<!>
|
a = 57
|
||||||
a = <!ASSIGNMENT_TYPE_MISMATCH!>x<!>
|
a = x
|
||||||
if (arg is String) {
|
if (arg is String) {
|
||||||
a = arg
|
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
|
// !LANGUAGE: +NoBuilderInferenceWithoutAnnotationRestriction
|
||||||
|
// FIR_DUMP
|
||||||
|
|
||||||
class Foo<T : Any> {
|
class Foo<T : Any> {
|
||||||
fun doSmthng(arg: T) {}
|
fun doSmthng(arg: T) {}
|
||||||
|
|||||||
Reference in New Issue
Block a user