[FIR] Fix inference of postponed lambdas if containg call has explicit type arguments
This commit is contained in:
committed by
TeamCityServer
parent
fbab32c4dd
commit
def799cc4e
+6
@@ -2859,6 +2859,12 @@ public class DiagnosisCompilerFirTestdataTestGenerated extends AbstractDiagnosis
|
|||||||
runTest("compiler/fir/analysis-tests/testData/resolve/inference/lambdaInElvis.kt");
|
runTest("compiler/fir/analysis-tests/testData/resolve/inference/lambdaInElvis.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("lambdaWithoutExpectedType.kt")
|
||||||
|
public void testLambdaWithoutExpectedType() throws Exception {
|
||||||
|
runTest("compiler/fir/analysis-tests/testData/resolve/inference/lambdaWithoutExpectedType.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("lambdasReturns.kt")
|
@TestMetadata("lambdasReturns.kt")
|
||||||
public void testLambdasReturns() throws Exception {
|
public void testLambdasReturns() throws Exception {
|
||||||
|
|||||||
+5
@@ -2511,6 +2511,11 @@ public class LazyBodyIsNotTouchedTilContractsPhaseTestGenerated extends Abstract
|
|||||||
runTest("compiler/fir/analysis-tests/testData/resolve/inference/lambdaInElvis.kt");
|
runTest("compiler/fir/analysis-tests/testData/resolve/inference/lambdaInElvis.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("lambdaWithoutExpectedType.kt")
|
||||||
|
public void testLambdaWithoutExpectedType() throws Exception {
|
||||||
|
runTest("compiler/fir/analysis-tests/testData/resolve/inference/lambdaWithoutExpectedType.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("lambdasReturns.kt")
|
@TestMetadata("lambdasReturns.kt")
|
||||||
public void testLambdasReturns() throws Exception {
|
public void testLambdasReturns() throws Exception {
|
||||||
runTest("compiler/fir/analysis-tests/testData/resolve/inference/lambdasReturns.kt");
|
runTest("compiler/fir/analysis-tests/testData/resolve/inference/lambdasReturns.kt");
|
||||||
|
|||||||
+60
@@ -0,0 +1,60 @@
|
|||||||
|
FILE: lambdaWithoutExpectedType.kt
|
||||||
|
public abstract interface XdEntity : R|kotlin/Any| {
|
||||||
|
}
|
||||||
|
public abstract interface XdEntityType<out T : R|XdEntity|> : R|kotlin/Any| {
|
||||||
|
}
|
||||||
|
public abstract interface XdNaturalEntityType<T : R|XdEntity|> : R|XdEntityType<T>| {
|
||||||
|
}
|
||||||
|
public final class XdProject : R|XdEntity| {
|
||||||
|
public constructor(name: R|kotlin/String|): R|XdProject| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
public final var name: R|kotlin/String| = R|<local>/name|
|
||||||
|
public get(): R|kotlin/String|
|
||||||
|
public set(value: R|kotlin/String|): R|kotlin/Unit|
|
||||||
|
|
||||||
|
public final companion object Companion : R|XdNaturalEntityType<XdProject>| {
|
||||||
|
private constructor(): R|XdProject.Companion| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public abstract interface XdSearchingNode : R|kotlin/Any| {
|
||||||
|
}
|
||||||
|
public abstract interface XdQuery<out T : R|XdEntity|> : R|kotlin/Any| {
|
||||||
|
}
|
||||||
|
public final fun <T : R|XdEntity|> R|XdQuery<T>|.firstOrNull(): R|T?| {
|
||||||
|
^firstOrNull Null(null)
|
||||||
|
}
|
||||||
|
public final object FilteringContext : R|kotlin/Any| {
|
||||||
|
private constructor(): R|FilteringContext| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
public final infix fun <T : R|kotlin/Comparable<T>|> R|T?|.eq(value: R|T?|): R|XdSearchingNode| {
|
||||||
|
^eq Null(null)!!
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public final fun <T : R|XdEntity|> R|XdEntityType<T>|.filter(clause: R|FilteringContext.(T) -> XdSearchingNode|): R|XdQuery<T>| {
|
||||||
|
^filter Null(null)!!
|
||||||
|
}
|
||||||
|
public abstract interface XdIssue : R|kotlin/Any| {
|
||||||
|
}
|
||||||
|
public abstract interface XdIssueFolder : R|kotlin/Any| {
|
||||||
|
}
|
||||||
|
public final fun test(): R|kotlin/Unit| {
|
||||||
|
lval array: R|kotlin/Array<kotlin/Any>| = R|kotlin/arrayOf|<R|kotlin/Any|>(vararg(String(Project), arrayOf@fun <anonymous>(): R|XdProject?| <inline=Unknown, kind=UNKNOWN> {
|
||||||
|
^ Q|XdProject|.R|/filter|<R|XdProject|>(<L> = filter@fun R|FilteringContext|.<anonymous>(it: R|XdProject|): R|XdSearchingNode| <inline=NoInline> {
|
||||||
|
^ (this@R|special/anonymous|, R|<local>/it|.R|/XdProject.name|).R|/FilteringContext.eq|<R|kotlin/String|>(String(foo))
|
||||||
|
}
|
||||||
|
).R|/firstOrNull|<R|XdProject|>()
|
||||||
|
}
|
||||||
|
, arrayOf@fun <anonymous>(<unused var>: R|XdIssue|, <unused var>: R|XdIssueFolder|): R|kotlin/Unit| <inline=Unknown, kind=UNKNOWN> {
|
||||||
|
^@arrayOf Unit
|
||||||
|
}
|
||||||
|
))
|
||||||
|
}
|
||||||
+34
@@ -0,0 +1,34 @@
|
|||||||
|
// WITH_STDLIB
|
||||||
|
|
||||||
|
interface XdEntity
|
||||||
|
|
||||||
|
interface XdEntityType<out T : XdEntity>
|
||||||
|
interface XdNaturalEntityType<T : XdEntity> : XdEntityType<T>
|
||||||
|
|
||||||
|
class XdProject(var name: String) : XdEntity {
|
||||||
|
companion object : XdNaturalEntityType<XdProject> {}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface XdSearchingNode
|
||||||
|
interface XdQuery<out T : XdEntity>
|
||||||
|
|
||||||
|
fun <T : XdEntity> XdQuery<T>.firstOrNull(): T? = null
|
||||||
|
|
||||||
|
object FilteringContext {
|
||||||
|
infix fun <T : Comparable<T>> T?.eq(value: T?): XdSearchingNode = null!!
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T : XdEntity> XdEntityType<T>.filter(clause: FilteringContext.(T) -> XdSearchingNode): XdQuery<T> {
|
||||||
|
return null!!
|
||||||
|
}
|
||||||
|
|
||||||
|
interface XdIssue
|
||||||
|
interface XdIssueFolder
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
val array = arrayOf<Any>(
|
||||||
|
"Project",
|
||||||
|
{ XdProject.filter { it.name eq "foo" }.firstOrNull() },
|
||||||
|
{ _: XdIssue, _: XdIssueFolder -> }
|
||||||
|
)
|
||||||
|
}
|
||||||
+6
@@ -2859,6 +2859,12 @@ public class FirDiagnosticTestGenerated extends AbstractFirDiagnosticTest {
|
|||||||
runTest("compiler/fir/analysis-tests/testData/resolve/inference/lambdaInElvis.kt");
|
runTest("compiler/fir/analysis-tests/testData/resolve/inference/lambdaInElvis.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("lambdaWithoutExpectedType.kt")
|
||||||
|
public void testLambdaWithoutExpectedType() throws Exception {
|
||||||
|
runTest("compiler/fir/analysis-tests/testData/resolve/inference/lambdaWithoutExpectedType.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("lambdasReturns.kt")
|
@TestMetadata("lambdasReturns.kt")
|
||||||
public void testLambdasReturns() throws Exception {
|
public void testLambdasReturns() throws Exception {
|
||||||
|
|||||||
+6
@@ -2859,6 +2859,12 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
|
|||||||
runTest("compiler/fir/analysis-tests/testData/resolve/inference/lambdaInElvis.kt");
|
runTest("compiler/fir/analysis-tests/testData/resolve/inference/lambdaInElvis.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("lambdaWithoutExpectedType.kt")
|
||||||
|
public void testLambdaWithoutExpectedType() throws Exception {
|
||||||
|
runTest("compiler/fir/analysis-tests/testData/resolve/inference/lambdaWithoutExpectedType.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("lambdasReturns.kt")
|
@TestMetadata("lambdasReturns.kt")
|
||||||
public void testLambdasReturns() throws Exception {
|
public void testLambdasReturns() throws Exception {
|
||||||
|
|||||||
+14
-1
@@ -15,9 +15,12 @@ import org.jetbrains.kotlin.fir.resolve.calls.CheckerSink
|
|||||||
import org.jetbrains.kotlin.fir.resolve.calls.ResolutionContext
|
import org.jetbrains.kotlin.fir.resolve.calls.ResolutionContext
|
||||||
import org.jetbrains.kotlin.fir.resolve.createFunctionalType
|
import org.jetbrains.kotlin.fir.resolve.createFunctionalType
|
||||||
import org.jetbrains.kotlin.fir.resolve.inference.model.ConeArgumentConstraintPosition
|
import org.jetbrains.kotlin.fir.resolve.inference.model.ConeArgumentConstraintPosition
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.inference.model.ConeExplicitTypeParameterConstraintPosition
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder
|
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.addSubtypeConstraintIfCompatible
|
import org.jetbrains.kotlin.resolve.calls.inference.addSubtypeConstraintIfCompatible
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintKind
|
||||||
|
import org.jetbrains.kotlin.types.model.typeConstructor
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
|
||||||
fun Candidate.preprocessLambdaArgument(
|
fun Candidate.preprocessLambdaArgument(
|
||||||
@@ -31,7 +34,17 @@ fun Candidate.preprocessLambdaArgument(
|
|||||||
returnTypeVariable: ConeTypeVariableForLambdaReturnType? = null
|
returnTypeVariable: ConeTypeVariableForLambdaReturnType? = null
|
||||||
): PostponedResolvedAtom {
|
): PostponedResolvedAtom {
|
||||||
if (expectedType != null && expectedTypeRef != null && !duringCompletion && csBuilder.isTypeVariable(expectedType)) {
|
if (expectedType != null && expectedTypeRef != null && !duringCompletion && csBuilder.isTypeVariable(expectedType)) {
|
||||||
return LambdaWithTypeVariableAsExpectedTypeAtom(argument, expectedType, expectedTypeRef, this)
|
val expectedTypeVariableWithConstraints = csBuilder.currentStorage().notFixedTypeVariables[expectedType.typeConstructor(context.typeContext)]
|
||||||
|
|
||||||
|
if (expectedTypeVariableWithConstraints != null) {
|
||||||
|
val explicitTypeArgument = expectedTypeVariableWithConstraints.constraints.find {
|
||||||
|
it.kind == ConstraintKind.EQUALITY && it.position.from is ConeExplicitTypeParameterConstraintPosition
|
||||||
|
}?.type as ConeKotlinType?
|
||||||
|
|
||||||
|
if (explicitTypeArgument == null || explicitTypeArgument.typeArguments.isNotEmpty()) {
|
||||||
|
return LambdaWithTypeVariableAsExpectedTypeAtom(argument, expectedType, expectedTypeRef, this)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val anonymousFunction = argument.anonymousFunction
|
val anonymousFunction = argument.anonymousFunction
|
||||||
|
|||||||
Reference in New Issue
Block a user