FIR: Fix inference of builder-inference function from expect type

Previously, such calls were being completed with FULL mode and incorrect
INFERENCE_NO_INFORMATION_FOR_PARAMETER has been reported
This commit is contained in:
Denis.Zharkov
2021-06-01 21:01:46 +03:00
committed by TeamCityServer
parent 18e93b50d9
commit 592256976e
14 changed files with 72 additions and 58 deletions
@@ -20,7 +20,7 @@ FILE: KtFirCompositeScope.kt
public final fun getAllNames(): R|kotlin/collections/Set<kotlin/String>| {
^getAllNames R|/withValidityAssertion|<R|kotlin/collections/Set<kotlin/String>|>(<L> = withValidityAssertion@fun <anonymous>(): R|kotlin/collections/Set<kotlin/String>| <inline=Inline, kind=UNKNOWN> {
^ R|/buildSet|<R|kotlin/String|>(<L> = buildSet@fun R|kotlin/collections/MutableSet<kotlin/String>|.<anonymous>(): R|kotlin/Unit| <inline=Inline, kind=UNKNOWN> {
this@R|/KtFirCompositeScope|.R|/KtFirCompositeScope.subScopes|.R|kotlin/collections/flatMapTo|<R|KtScope|, R|kotlin/String|, R|kotlin/collections/MutableSet<kotlin/String>|>(this@R|special/anonymous|, <L> = flatMapTo@fun <anonymous>(it: R|KtScope|): R|kotlin/collections/Iterable<kotlin/String>| <inline=Inline, kind=UNKNOWN> {
this@R|/KtFirCompositeScope|.R|/KtFirCompositeScope.subScopes|.R|kotlin/collections/flatMapTo|<R|KtScope|, R|kotlin/String|, R|kotlin/collections/MutableSet<Stub: TypeVariable(E)>|>(this@R|special/anonymous|, <L> = flatMapTo@fun <anonymous>(it: R|KtScope|): R|kotlin/collections/Iterable<kotlin/String>| <inline=Inline, kind=UNKNOWN> {
^ R|<local>/it|.R|/KtScope.getAllNames|()
}
)
@@ -17677,6 +17677,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/inference/builderInference/constraintsBetweenTwoStubVariables.kt");
}
@Test
@TestMetadata("inferFromExpectedType.kt")
public void testInferFromExpectedType() throws Exception {
runTest("compiler/testData/codegen/box/inference/builderInference/inferFromExpectedType.kt");
}
@Test
@TestMetadata("intersect.kt")
public void testIntersect() throws Exception {
@@ -5,7 +5,6 @@
package org.jetbrains.kotlin.fir
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.fir.expressions.FirResolvable
import org.jetbrains.kotlin.fir.expressions.FirStatement
import org.jetbrains.kotlin.fir.resolve.calls.Candidate
@@ -138,7 +137,8 @@ class FirOverloadByLambdaReturnTypeResolver(
val results = postponedArgumentsAnalyzer.analyzeLambda(
firstCandidate.system.asPostponedArgumentsAnalyzerContext(),
firstAtom,
firstCandidate
firstCandidate,
ConstraintSystemCompletionMode.FULL,
)
while (iterator.hasNext()) {
val (candidate, atom) = iterator.next()
@@ -147,7 +147,8 @@ class FirOverloadByLambdaReturnTypeResolver(
candidate.system.asPostponedArgumentsAnalyzerContext(),
atom,
candidate,
results
results,
ConstraintSystemCompletionMode.FULL,
)
}
@@ -108,7 +108,8 @@ class FirBuilderInferenceSession(
override fun inferPostponedVariables(
lambda: ResolvedLambdaAtom,
initialStorage: ConstraintStorage
initialStorage: ConstraintStorage,
completionMode: ConstraintSystemCompletionMode
): Map<ConeTypeVariableTypeConstructor, ConeKotlinType>? {
val (commonSystem, effectivelyEmptyConstraintSystem) = buildCommonSystem(initialStorage)
if (effectivelyEmptyConstraintSystem) {
@@ -120,7 +121,7 @@ class FirBuilderInferenceSession(
@Suppress("UNCHECKED_CAST")
components.callCompleter.completer.complete(
context,
ConstraintSystemCompletionMode.FULL,
completionMode,
partiallyResolvedCalls.map { it.first as FirStatement },
components.session.builtinTypes.unitType.type, resolutionContext,
collectVariablesFromContext = true
@@ -167,7 +167,7 @@ class FirCallCompleter(
initialType,
transformer.resolutionContext
) {
analyzer.analyze(candidate.system.asPostponedArgumentsAnalyzerContext(), it, candidate)
analyzer.analyze(candidate.system.asPostponedArgumentsAnalyzerContext(), it, candidate, completionMode)
}
}
@@ -53,7 +53,8 @@ class FirDelegatedPropertyInferenceSession(
override fun inferPostponedVariables(
lambda: ResolvedLambdaAtom,
initialStorage: ConstraintStorage
initialStorage: ConstraintStorage,
completionMode: ConstraintSystemCompletionMode
): Map<ConeTypeVariableTypeConstructor, ConeKotlinType>? = null
override fun <T> shouldCompleteResolvedSubAtomsOf(call: T): Boolean where T : FirResolvable, T : FirStatement = true
@@ -76,7 +77,8 @@ class FirDelegatedPropertyInferenceSession(
postponedArgumentsAnalyzer.analyze(
commonSystem.asPostponedArgumentsAnalyzerContext(),
it,
resolvedCalls.first().candidate
resolvedCalls.first().candidate,
ConstraintSystemCompletionMode.FULL,
)
}
}
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.fir.expressions.FirStatement
import org.jetbrains.kotlin.fir.resolve.calls.Candidate
import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.fir.types.ConeTypeVariableTypeConstructor
import org.jetbrains.kotlin.resolve.calls.inference.components.ConstraintSystemCompletionMode
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
abstract class FirInferenceSession {
@@ -27,6 +28,7 @@ abstract class FirInferenceSession {
abstract fun inferPostponedVariables(
lambda: ResolvedLambdaAtom,
initialStorage: ConstraintStorage,
completionMode: ConstraintSystemCompletionMode,
// TODO: diagnostic holder
): Map<ConeTypeVariableTypeConstructor, ConeKotlinType>?
@@ -47,7 +49,8 @@ abstract class FirStubInferenceSession : FirInferenceSession() {
override fun inferPostponedVariables(
lambda: ResolvedLambdaAtom,
initialStorage: ConstraintStorage
initialStorage: ConstraintStorage,
completionMode: ConstraintSystemCompletionMode
): Map<ConeTypeVariableTypeConstructor, ConeKotlinType>? = null
override fun <T> writeOnlyStubs(call: T): Boolean where T : FirResolvable, T : FirStatement = false
@@ -16,11 +16,15 @@ import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedReferenceError
import org.jetbrains.kotlin.fir.resolve.inference.model.ConeLambdaArgumentConstraintPosition
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.resolve.transformers.StoreNameReference
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.fir.types.ConeTypeVariable
import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.fir.types.isMarkedNullable
import org.jetbrains.kotlin.resolve.calls.components.PostponedArgumentsAnalyzerContext
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder
import org.jetbrains.kotlin.resolve.calls.inference.components.ConstraintSystemCompletionMode
import org.jetbrains.kotlin.resolve.calls.inference.model.CoroutinePosition
import org.jetbrains.kotlin.types.model.StubTypeMarker
import org.jetbrains.kotlin.types.model.TypeVariableMarker
@@ -52,14 +56,15 @@ class PostponedArgumentsAnalyzer(
fun analyze(
c: PostponedArgumentsAnalyzerContext,
argument: PostponedResolvedAtom,
candidate: Candidate
candidate: Candidate,
completionMode: ConstraintSystemCompletionMode
) {
when (argument) {
is ResolvedLambdaAtom ->
analyzeLambda(c, argument, candidate)
analyzeLambda(c, argument, candidate, completionMode)
is LambdaWithTypeVariableAsExpectedTypeAtom ->
analyzeLambda(c, argument.transformToResolvedLambda(c.getBuilder(), resolutionContext), candidate)
analyzeLambda(c, argument.transformToResolvedLambda(c.getBuilder(), resolutionContext), candidate, completionMode)
is ResolvedCallableReferenceAtom -> processCallableReference(argument, candidate)
@@ -106,7 +111,8 @@ class PostponedArgumentsAnalyzer(
fun analyzeLambda(
c: PostponedArgumentsAnalyzerContext,
lambda: ResolvedLambdaAtom,
candidate: Candidate
candidate: Candidate,
completionMode: ConstraintSystemCompletionMode,
//diagnosticHolder: KotlinDiagnosticsHolder
): ReturnArgumentsAnalysisResult {
val unitType = components.session.builtinTypes.unitType.type
@@ -135,7 +141,15 @@ class PostponedArgumentsAnalyzer(
expectedTypeForReturnArguments,
stubsForPostponedVariables
)
applyResultsOfAnalyzedLambdaToCandidateSystem(c, lambda, candidate, results, expectedTypeForReturnArguments, ::substitute)
applyResultsOfAnalyzedLambdaToCandidateSystem(
c,
lambda,
candidate,
results,
completionMode,
expectedTypeForReturnArguments,
::substitute
)
return results
}
@@ -144,6 +158,7 @@ class PostponedArgumentsAnalyzer(
lambda: ResolvedLambdaAtom,
candidate: Candidate,
results: ReturnArgumentsAnalysisResult,
completionMode: ConstraintSystemCompletionMode,
expectedReturnType: ConeKotlinType? = null,
substitute: (ConeKotlinType) -> ConeKotlinType = c.createSubstituteFunctorForLambdaAnalysis()
) {
@@ -151,7 +166,7 @@ class PostponedArgumentsAnalyzer(
if (inferenceSession != null) {
val storageSnapshot = c.getBuilder().currentStorage()
val postponedVariables = inferenceSession.inferPostponedVariables(lambda, storageSnapshot)
val postponedVariables = inferenceSession.inferPostponedVariables(lambda, storageSnapshot, completionMode)
if (postponedVariables == null) {
c.getBuilder().removePostponedVariables()