[FE 1.0] Take care standalone lambdas during updating types in the builder inference
^KT-50520 Fixed
This commit is contained in:
committed by
teamcity
parent
c25e07119c
commit
b411eb36e8
+6
@@ -19558,6 +19558,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/inference/builderInference/kt49887.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt50520.kt")
|
||||
public void testKt50520() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inference/builderInference/kt50520.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt51988.kt")
|
||||
public void testKt51988() throws Exception {
|
||||
|
||||
@@ -190,9 +190,6 @@ class LocalVariableResolver(
|
||||
initializeWithDefaultGetterSetter(propertyDescriptor)
|
||||
trace.record(BindingContext.VARIABLE, variable, propertyDescriptor)
|
||||
result = propertyDescriptor
|
||||
if (inferenceSession is BuilderInferenceSession) {
|
||||
inferenceSession.addLocalVariable(variable)
|
||||
}
|
||||
} else {
|
||||
val variableDescriptor = resolveLocalVariableDescriptorWithType(scope, variable, null, trace)
|
||||
// For a local variable the type must not be deferred
|
||||
@@ -200,11 +197,11 @@ class LocalVariableResolver(
|
||||
variableDescriptor, scope, variable, dataFlowInfo, inferenceSession, trace, local = true
|
||||
)
|
||||
variableDescriptor.setOutType(type)
|
||||
if (inferenceSession is BuilderInferenceSession) {
|
||||
inferenceSession.addLocalVariable(variable)
|
||||
}
|
||||
result = variableDescriptor
|
||||
}
|
||||
if (inferenceSession is BuilderInferenceSession) {
|
||||
inferenceSession.addExpression(variable)
|
||||
}
|
||||
variableTypeAndInitializerResolver
|
||||
.setConstantForVariableIfNeeded(result, scope, variable, dataFlowInfo, type, inferenceSession, trace)
|
||||
// Type annotations also should be resolved
|
||||
|
||||
+44
-48
@@ -8,15 +8,15 @@ package org.jetbrains.kotlin.resolve.calls.inference
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.impl.*
|
||||
import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.anyDescendantOfType
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
|
||||
import org.jetbrains.kotlin.psi.psiUtil.isAncestor
|
||||
import org.jetbrains.kotlin.resolve.*
|
||||
import org.jetbrains.kotlin.resolve.calls.ArgumentTypeResolver
|
||||
import org.jetbrains.kotlin.resolve.calls.util.shouldBeSubstituteWithStubTypes
|
||||
import org.jetbrains.kotlin.resolve.calls.util.toOldSubstitution
|
||||
import org.jetbrains.kotlin.resolve.calls.components.*
|
||||
import org.jetbrains.kotlin.resolve.calls.components.candidate.ResolutionCandidate
|
||||
import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext
|
||||
@@ -25,6 +25,8 @@ import org.jetbrains.kotlin.resolve.calls.inference.model.*
|
||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.*
|
||||
import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject
|
||||
import org.jetbrains.kotlin.resolve.calls.util.shouldBeSubstituteWithStubTypes
|
||||
import org.jetbrains.kotlin.resolve.calls.util.toOldSubstitution
|
||||
import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.hasBuilderInferenceAnnotation
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.shouldBeSubstituteWithStubTypes
|
||||
@@ -73,11 +75,7 @@ class BuilderInferenceSession(
|
||||
}
|
||||
|
||||
private val commonCalls = arrayListOf<PSICompletedCallInfo>()
|
||||
|
||||
private val localVariables = arrayListOf<KtVariableDeclaration>()
|
||||
|
||||
// These calls come from the old type inference
|
||||
private val oldDoubleColonExpressionCalls = arrayListOf<KtExpression>()
|
||||
private val commonExpressions = arrayListOf<KtExpression>()
|
||||
|
||||
private var hasInapplicableCall = false
|
||||
|
||||
@@ -130,10 +128,6 @@ class BuilderInferenceSession(
|
||||
}
|
||||
}
|
||||
|
||||
fun addOldCallableReferenceCalls(callExpression: KtExpression) {
|
||||
oldDoubleColonExpressionCalls.add(callExpression)
|
||||
}
|
||||
|
||||
override fun addCompletedCallInfo(callInfo: CompletedCallInfo) {
|
||||
require(callInfo is PSICompletedCallInfo) { "Wrong instance of callInfo: $callInfo" }
|
||||
|
||||
@@ -158,8 +152,8 @@ class BuilderInferenceSession(
|
||||
}
|
||||
}
|
||||
|
||||
fun addLocalVariable(variable: KtVariableDeclaration) {
|
||||
localVariables.add(variable)
|
||||
fun addExpression(expression: KtExpression) {
|
||||
commonExpressions.add(expression)
|
||||
}
|
||||
|
||||
private fun anyReceiverContainStubType(descriptor: CallableDescriptor): Boolean {
|
||||
@@ -180,7 +174,6 @@ class BuilderInferenceSession(
|
||||
return null
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalStdlibApi::class)
|
||||
private fun findAllParentBuildInferenceSessions() = buildList {
|
||||
var currentSession: BuilderInferenceSession? = findParentBuildInferenceSession()
|
||||
|
||||
@@ -259,7 +252,7 @@ class BuilderInferenceSession(
|
||||
kotlinConstraintSystemCompleter.completeConstraintSystem(
|
||||
commonSystem.asConstraintSystemCompleterContext(),
|
||||
builtIns.unitType,
|
||||
partiallyResolvedCallsInfo.map { it.callResolutionResult.resultCallAtom },
|
||||
commonPartiallyResolvedCalls.map { it.callResolutionResult.resultCallAtom },
|
||||
completionMode,
|
||||
diagnosticsHolder
|
||||
)
|
||||
@@ -277,7 +270,6 @@ class BuilderInferenceSession(
|
||||
return commonSystem.fixedTypeVariables.cast() // TODO: SUB
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalStdlibApi::class)
|
||||
private fun getNestedBuilderInferenceSessions() = buildList {
|
||||
for (nestedSession in nestedInferenceSessions) {
|
||||
when (nestedSession) {
|
||||
@@ -448,13 +440,9 @@ class BuilderInferenceSession(
|
||||
|
||||
integrateConstraints(initialStorage, nonFixedToVariablesSubstitutor, false)
|
||||
|
||||
for (call in commonCalls) {
|
||||
for (call in commonCalls + commonPartiallyResolvedCalls) {
|
||||
val storage = call.callResolutionResult.constraintSystem.getBuilder().currentStorage()
|
||||
integrateConstraints(storage, nonFixedToVariablesSubstitutor, false)
|
||||
}
|
||||
for (call in partiallyResolvedCallsInfo) {
|
||||
val storage = call.callResolutionResult.constraintSystem.getBuilder().currentStorage()
|
||||
integrateConstraints(storage, nonFixedToVariablesSubstitutor, true)
|
||||
integrateConstraints(storage, nonFixedToVariablesSubstitutor, shouldIntegrateAllConstraints = call is PSIPartialCallInfo)
|
||||
}
|
||||
|
||||
return commonSystem.notFixedTypeVariables.all { it.value.constraints.isEmpty() }
|
||||
@@ -470,10 +458,31 @@ class BuilderInferenceSession(
|
||||
)
|
||||
}
|
||||
|
||||
private fun updateLocalVariable(localVariable: KtVariableDeclaration, substitutor: NewTypeSubstitutor) {
|
||||
val descriptor = trace[BindingContext.VARIABLE, localVariable] as? LocalVariableDescriptor
|
||||
if (descriptor != null && descriptor.type.shouldBeUpdated()) {
|
||||
descriptor.setOutType(substitutor.safeSubstitute(descriptor.type.unwrap()))
|
||||
private fun updateExpressionDescriptorAndType(expression: KtExpression, substitutor: NewTypeSubstitutor) {
|
||||
val currentExpressionType = trace.getType(expression)
|
||||
if (currentExpressionType != null) {
|
||||
trace.recordType(expression, substitutor.safeSubstitute(currentExpressionType.unwrap()))
|
||||
}
|
||||
|
||||
val (currentDescriptorType, updateDescriptorType) = when (expression) {
|
||||
is KtLambdaExpression -> {
|
||||
val descriptor = trace[BindingContext.FUNCTION, expression.functionLiteral] as? AnonymousFunctionDescriptor ?: return
|
||||
val currentType = descriptor.returnType ?: return
|
||||
currentType to descriptor::setReturnType
|
||||
}
|
||||
is KtVariableDeclaration -> {
|
||||
val descriptor = trace[BindingContext.VARIABLE, expression] as? LocalVariableDescriptor ?: return
|
||||
descriptor.type to descriptor::setOutType
|
||||
}
|
||||
is KtDoubleColonExpression -> {
|
||||
completeDoubleColonExpression(expression, substitutor)
|
||||
return
|
||||
}
|
||||
else -> return
|
||||
}
|
||||
|
||||
if (currentDescriptorType.shouldBeUpdated()) {
|
||||
updateDescriptorType(substitutor.safeSubstitute(currentDescriptorType.unwrap()))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -513,12 +522,6 @@ class BuilderInferenceSession(
|
||||
atomCompleter.substituteFunctionLiteralDescriptor(resolvedAtom = null, descriptor = declarationDescriptor, substitutor)
|
||||
}
|
||||
|
||||
val recordedType = trace.getType(expression)
|
||||
|
||||
if (recordedType != null) {
|
||||
trace.recordType(expression, substitutor.safeSubstitute(recordedType.unwrap()))
|
||||
}
|
||||
|
||||
val targetExpression = when (expression) {
|
||||
is KtCallableReferenceExpression -> expression.callableReference
|
||||
is KtClassLiteralExpression -> expression.receiverExpression
|
||||
@@ -610,25 +613,18 @@ class BuilderInferenceSession(
|
||||
topLevelCallContext.replaceBindingTrace(findTopLevelTrace()).replaceInferenceSession(this)
|
||||
)
|
||||
|
||||
for (localVariable in localVariables) {
|
||||
updateLocalVariable(localVariable, nonFixedTypesToResultSubstitutor)
|
||||
for (expression in commonExpressions) {
|
||||
updateExpressionDescriptorAndType(expression, nonFixedTypesToResultSubstitutor)
|
||||
}
|
||||
|
||||
for (completedCall in commonCalls) {
|
||||
updateCall(completedCall, nonFixedTypesToResultSubstitutor, nonFixedTypesToResult)
|
||||
reportErrors(completedCall, completedCall.resolvedCall, errors)
|
||||
for (call in commonCalls) {
|
||||
updateCall(call, nonFixedTypesToResultSubstitutor, nonFixedTypesToResult)
|
||||
reportErrors(call, call.resolvedCall, errors)
|
||||
}
|
||||
|
||||
for (callInfo in partiallyResolvedCallsInfo) {
|
||||
val resolvedCall = completeCall(callInfo, atomCompleter) ?: continue
|
||||
reportErrors(callInfo, resolvedCall, errors)
|
||||
}
|
||||
|
||||
for (call in oldDoubleColonExpressionCalls) {
|
||||
when (call) {
|
||||
is KtDoubleColonExpression -> completeDoubleColonExpression(call, nonFixedTypesToResultSubstitutor)
|
||||
else -> throw Exception("Unsupported call expression type")
|
||||
}
|
||||
for (call in commonPartiallyResolvedCalls) {
|
||||
val resolvedCall = completeCall(call, atomCompleter) ?: continue
|
||||
reportErrors(call, resolvedCall, errors)
|
||||
}
|
||||
|
||||
atomCompleter.completeAll(lambda)
|
||||
|
||||
+4
-4
@@ -28,7 +28,7 @@ abstract class StubTypesBasedInferenceSession<D : CallableDescriptor>(
|
||||
protected val callComponents: KotlinCallComponents,
|
||||
val builtIns: KotlinBuiltIns
|
||||
) : InferenceSession {
|
||||
protected val partiallyResolvedCallsInfo = arrayListOf<PSIPartialCallInfo>()
|
||||
protected val commonPartiallyResolvedCalls = arrayListOf<PSIPartialCallInfo>()
|
||||
val errorCallsInfo = arrayListOf<PSIErrorCallInfo<D>>()
|
||||
private val completedCalls = hashSetOf<ResolvedAtom>()
|
||||
protected val nestedInferenceSessions = hashSetOf<StubTypesBasedInferenceSession<*>>()
|
||||
@@ -49,7 +49,7 @@ abstract class StubTypesBasedInferenceSession<D : CallableDescriptor>(
|
||||
if (callInfo !is PSIPartialCallInfo) {
|
||||
throw AssertionError("Call info for $callInfo should be instance of PSIPartialCallInfo")
|
||||
}
|
||||
partiallyResolvedCallsInfo.add(callInfo)
|
||||
commonPartiallyResolvedCalls.add(callInfo)
|
||||
}
|
||||
|
||||
override fun addCompletedCallInfo(callInfo: CompletedCallInfo) {
|
||||
@@ -65,7 +65,7 @@ abstract class StubTypesBasedInferenceSession<D : CallableDescriptor>(
|
||||
}
|
||||
|
||||
override fun currentConstraintSystem(): ConstraintStorage {
|
||||
return partiallyResolvedCallsInfo.lastOrNull()?.callResolutionResult?.constraintSystem?.getBuilder()?.currentStorage()
|
||||
return commonPartiallyResolvedCalls.lastOrNull()?.callResolutionResult?.constraintSystem?.getBuilder()?.currentStorage()
|
||||
?: ConstraintStorage.Empty
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ abstract class StubTypesBasedInferenceSession<D : CallableDescriptor>(
|
||||
override fun shouldCompleteResolvedSubAtomsOf(resolvedCallAtom: ResolvedCallAtom) = true
|
||||
|
||||
fun resolveCandidates(resolutionCallbacks: KotlinResolutionCallbacks): List<ResolutionResultCallInfo<D>> {
|
||||
val resolvedCallsInfo = partiallyResolvedCallsInfo.toList()
|
||||
val resolvedCallsInfo = commonPartiallyResolvedCalls.toList()
|
||||
|
||||
val diagnosticHolder = KotlinDiagnosticsHolder.SimpleHolder()
|
||||
|
||||
|
||||
+2
-2
@@ -111,7 +111,7 @@ class DoubleColonExpressionResolver(
|
||||
val result = resolveDoubleColonLHS(expression, c)
|
||||
|
||||
if (c.inferenceSession is BuilderInferenceSession && result?.type?.contains { it is StubTypeForBuilderInference } == true) {
|
||||
c.inferenceSession.addOldCallableReferenceCalls(expression)
|
||||
c.inferenceSession.addExpression(expression)
|
||||
}
|
||||
|
||||
if (result != null && !result.type.isError) {
|
||||
@@ -557,7 +557,7 @@ class DoubleColonExpressionResolver(
|
||||
val dataFlowInfo = (lhs as? DoubleColonLHS.Expression)?.dataFlowInfo ?: c.dataFlowInfo
|
||||
|
||||
if (c.inferenceSession is BuilderInferenceSession && result?.contains { it is StubTypeForBuilderInference } == true) {
|
||||
c.inferenceSession.addOldCallableReferenceCalls(expression)
|
||||
c.inferenceSession.addExpression(expression)
|
||||
}
|
||||
|
||||
return dataFlowAnalyzer.checkType(createTypeInfo(result, dataFlowInfo), expression, c)
|
||||
|
||||
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.psi.psiUtil.getAnnotationEntries
|
||||
import org.jetbrains.kotlin.resolve.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext.EXPECTED_RETURN_TYPE
|
||||
import org.jetbrains.kotlin.resolve.calls.context.ContextDependency
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.BuilderInferenceSession
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.TypeVariableTypeConstructor
|
||||
import org.jetbrains.kotlin.resolve.checkers.TrailingCommaChecker
|
||||
import org.jetbrains.kotlin.resolve.checkers.UnderscoreChecker
|
||||
@@ -182,6 +183,10 @@ internal class FunctionsTypingVisitor(facade: ExpressionTypingInternals) : Expre
|
||||
functionDescriptor.createFunctionType(components.builtIns, suspendFunctionTypeExpected)!!
|
||||
)
|
||||
|
||||
if (context.inferenceSession is BuilderInferenceSession) {
|
||||
context.inferenceSession.addExpression(expression)
|
||||
}
|
||||
|
||||
if (functionTypeExpected) {
|
||||
// all checks were done before
|
||||
return createTypeInfo(resultType, context)
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
// WITH_STDLIB
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// FIR status: different behavour with FE 1.0, reported `NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER`
|
||||
|
||||
fun box(): String {
|
||||
buildList {
|
||||
val foo = { first() }
|
||||
add(0, foo)
|
||||
}
|
||||
return "OK"
|
||||
}
|
||||
+6
@@ -19096,6 +19096,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
runTest("compiler/testData/codegen/box/inference/builderInference/kt49887.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt50520.kt")
|
||||
public void testKt50520() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inference/builderInference/kt50520.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt51988.kt")
|
||||
public void testKt51988() throws Exception {
|
||||
|
||||
+6
@@ -19558,6 +19558,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
runTest("compiler/testData/codegen/box/inference/builderInference/kt49887.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt50520.kt")
|
||||
public void testKt50520() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inference/builderInference/kt50520.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt51988.kt")
|
||||
public void testKt51988() throws Exception {
|
||||
|
||||
+5
@@ -15868,6 +15868,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
runTest("compiler/testData/codegen/box/inference/builderInference/kt49887.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt50520.kt")
|
||||
public void testKt50520() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inference/builderInference/kt50520.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt51988.kt")
|
||||
public void testKt51988() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inference/builderInference/kt51988.kt");
|
||||
|
||||
+6
@@ -14856,6 +14856,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
runTest("compiler/testData/codegen/box/inference/builderInference/kt49887.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt50520.kt")
|
||||
public void testKt50520() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inference/builderInference/kt50520.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt51988.kt")
|
||||
public void testKt51988() throws Exception {
|
||||
|
||||
+6
@@ -14820,6 +14820,12 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
||||
runTest("compiler/testData/codegen/box/inference/builderInference/kt49887.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt50520.kt")
|
||||
public void testKt50520() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inference/builderInference/kt50520.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt51988.kt")
|
||||
public void testKt51988() throws Exception {
|
||||
|
||||
+5
@@ -13188,6 +13188,11 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest
|
||||
runTest("compiler/testData/codegen/box/inference/builderInference/kt49887.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt50520.kt")
|
||||
public void testKt50520() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inference/builderInference/kt50520.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt51988.kt")
|
||||
public void testKt51988() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inference/builderInference/kt51988.kt");
|
||||
|
||||
+6
@@ -15948,6 +15948,12 @@ public class NativeCodegenBoxTestGenerated extends AbstractNativeCodegenBoxTest
|
||||
runTest("compiler/testData/codegen/box/inference/builderInference/kt49887.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt50520.kt")
|
||||
public void testKt50520() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inference/builderInference/kt50520.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt51988.kt")
|
||||
public void testKt51988() throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user