NI: Support forking inference with heuristics
Mostly, it only affects FIR It partially allows to consider several variance of constraints like A<Int> & A<T> <: A<X_var> that are mostly brought by smart casts ^KT-49542 Fixed ^KT-50489 Relates
This commit is contained in:
+12
@@ -13803,6 +13803,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
||||
runTest("compiler/testData/diagnostics/tests/inference/selectOfLambdaWithExtensionEnabled.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("smartCastFork.kt")
|
||||
public void testSmartCastFork() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/smartCastFork.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("specialCallsWithCallableReferences.kt")
|
||||
public void testSpecialCallsWithCallableReferences() throws Exception {
|
||||
@@ -36583,6 +36589,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/inference/kt4975.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("plusAssignOnArrayList.kt")
|
||||
public void testPlusAssignOnArrayList() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/inference/plusAssignOnArrayList.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("recursiveFlexibleAssertions.kt")
|
||||
public void testRecursiveFlexibleAssertions() throws Exception {
|
||||
|
||||
+12
@@ -13803,6 +13803,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
|
||||
runTest("compiler/testData/diagnostics/tests/inference/selectOfLambdaWithExtensionEnabled.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("smartCastFork.kt")
|
||||
public void testSmartCastFork() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/smartCastFork.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("specialCallsWithCallableReferences.kt")
|
||||
public void testSpecialCallsWithCallableReferences() throws Exception {
|
||||
@@ -36583,6 +36589,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/inference/kt4975.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("plusAssignOnArrayList.kt")
|
||||
public void testPlusAssignOnArrayList() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/inference/plusAssignOnArrayList.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("recursiveFlexibleAssertions.kt")
|
||||
public void testRecursiveFlexibleAssertions() throws Exception {
|
||||
|
||||
+4
@@ -503,6 +503,10 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
||||
val ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_ANNOTATION by deprecationError<KtExpression>(LanguageFeature.ProhibitAssigningSingleElementsToVarargsInNamedForm)
|
||||
val REDUNDANT_SPREAD_OPERATOR_IN_NAMED_FORM_IN_ANNOTATION by warning<KtExpression>()
|
||||
val REDUNDANT_SPREAD_OPERATOR_IN_NAMED_FORM_IN_FUNCTION by warning<KtExpression>()
|
||||
|
||||
val INFERENCE_UNSUCCESSFUL_FORK by error<PsiElement> {
|
||||
parameter<String>("message")
|
||||
}
|
||||
}
|
||||
|
||||
val AMBIGUITY by object : DiagnosticGroup("Ambiguity") {
|
||||
|
||||
@@ -341,6 +341,7 @@ object FirErrors {
|
||||
val ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_ANNOTATION by deprecationError0<KtExpression>(ProhibitAssigningSingleElementsToVarargsInNamedForm)
|
||||
val REDUNDANT_SPREAD_OPERATOR_IN_NAMED_FORM_IN_ANNOTATION by warning0<KtExpression>()
|
||||
val REDUNDANT_SPREAD_OPERATOR_IN_NAMED_FORM_IN_FUNCTION by warning0<KtExpression>()
|
||||
val INFERENCE_UNSUCCESSFUL_FORK by error1<PsiElement, String>()
|
||||
|
||||
// Ambiguity
|
||||
val OVERLOAD_RESOLUTION_AMBIGUITY by error1<PsiElement, Collection<FirBasedSymbol<*>>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
||||
|
||||
+2
@@ -250,6 +250,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INCONSISTENT_TYPE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INCORRECT_CHARACTER_LITERAL
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INC_DEC_SHOULD_NOT_RETURN_UNIT
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INFERENCE_ERROR
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INFERENCE_UNSUCCESSFUL_FORK
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INFIX_MODIFIER_REQUIRED
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INITIALIZATION_BEFORE_DECLARATION
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INITIALIZER_REQUIRED_FOR_DESTRUCTURING_DECLARATION
|
||||
@@ -928,6 +929,7 @@ object FirErrorsDefaultMessages : BaseDiagnosticRendererFactory() {
|
||||
)
|
||||
map.put(REDUNDANT_SPREAD_OPERATOR_IN_NAMED_FORM_IN_ANNOTATION, "Redundant spread (*) operator")
|
||||
map.put(REDUNDANT_SPREAD_OPERATOR_IN_NAMED_FORM_IN_FUNCTION, "Redundant spread (*) operator")
|
||||
map.put(INFERENCE_UNSUCCESSFUL_FORK, "Unsuccessful inference fork at position: {0}", TO_STRING)
|
||||
|
||||
map.put(TYPE_MISMATCH, "Type mismatch: inferred type is {1} but {0} was expected", TO_STRING, TO_STRING, NOT_RENDERED)
|
||||
map.put(THROWABLE_TYPE_MISMATCH, "Throwable type mismatch: actual type is {0}", TO_STRING, NOT_RENDERED)
|
||||
|
||||
+6
@@ -370,6 +370,12 @@ private fun ConstraintSystemError.toDiagnostic(
|
||||
typeVariableName,
|
||||
)
|
||||
}
|
||||
is NoSuccessfulFork -> {
|
||||
FirErrors.INFERENCE_UNSUCCESSFUL_FORK.createOn(
|
||||
source,
|
||||
position.initialConstraint.asStringWithoutPosition(),
|
||||
)
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ sealed class CallKind(vararg resolutionSequence: ResolutionStage) {
|
||||
CheckDslScopeViolation,
|
||||
CheckLowPriorityInOverloadResolution,
|
||||
PostponedVariablesInitializerResolutionStage,
|
||||
ConstraintSystemForks
|
||||
)
|
||||
|
||||
object SyntheticSelect : CallKind(
|
||||
@@ -27,7 +28,8 @@ sealed class CallKind(vararg resolutionSequence: ResolutionStage) {
|
||||
CreateFreshTypeVariableSubstitutorStage,
|
||||
CollectTypeVariableUsagesInfo,
|
||||
CheckArguments,
|
||||
EagerResolveOfCallableReferences
|
||||
EagerResolveOfCallableReferences,
|
||||
ConstraintSystemForks,
|
||||
)
|
||||
|
||||
object Function : CallKind(
|
||||
@@ -47,6 +49,7 @@ sealed class CallKind(vararg resolutionSequence: ResolutionStage) {
|
||||
EagerResolveOfCallableReferences,
|
||||
CheckLowPriorityInOverloadResolution,
|
||||
PostponedVariablesInitializerResolutionStage,
|
||||
ConstraintSystemForks,
|
||||
)
|
||||
|
||||
object DelegatingConstructorCall : CallKind(
|
||||
@@ -62,6 +65,7 @@ sealed class CallKind(vararg resolutionSequence: ResolutionStage) {
|
||||
CheckDslScopeViolation,
|
||||
CheckArguments,
|
||||
EagerResolveOfCallableReferences,
|
||||
ConstraintSystemForks,
|
||||
)
|
||||
|
||||
object CallableReference : CallKind(
|
||||
@@ -84,7 +88,8 @@ sealed class CallKind(vararg resolutionSequence: ResolutionStage) {
|
||||
CreateFreshTypeVariableSubstitutorStage,
|
||||
CollectTypeVariableUsagesInfo,
|
||||
CheckArguments,
|
||||
EagerResolveOfCallableReferences
|
||||
EagerResolveOfCallableReferences,
|
||||
ConstraintSystemForks,
|
||||
)
|
||||
|
||||
internal class CustomForIde(vararg resolutionSequence: ResolutionStage) : CallKind(*resolutionSequence)
|
||||
|
||||
+20
-2
@@ -7,14 +7,19 @@ package org.jetbrains.kotlin.fir.resolve.calls
|
||||
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.FirVisibilityChecker
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.*
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.languageVersionSettings
|
||||
import org.jetbrains.kotlin.fir.matchingParameterFunctionType
|
||||
import org.jetbrains.kotlin.fir.references.FirSuperReference
|
||||
import org.jetbrains.kotlin.fir.resolve.directExpansionType
|
||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||
import org.jetbrains.kotlin.fir.resolve.inference.*
|
||||
import org.jetbrains.kotlin.fir.resolve.inference.ConeTypeParameterBasedTypeVariable
|
||||
import org.jetbrains.kotlin.fir.resolve.inference.ResolvedCallableReferenceAtom
|
||||
import org.jetbrains.kotlin.fir.resolve.inference.csBuilder
|
||||
import org.jetbrains.kotlin.fir.resolve.inference.hasBuilderInferenceAnnotation
|
||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
|
||||
import org.jetbrains.kotlin.fir.scopes.FirUnstableSmartcastTypeScope
|
||||
@@ -25,6 +30,7 @@ import org.jetbrains.kotlin.fir.symbols.SyntheticSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.ensureResolved
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.visibilityChecker
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
@@ -527,3 +533,15 @@ internal object CheckDeprecatedSinceKotlin : ResolutionStage() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal object ConstraintSystemForks : ResolutionStage() {
|
||||
override suspend fun check(candidate: Candidate, callInfo: CallInfo, sink: CheckerSink, context: ResolutionContext) {
|
||||
if (candidate.system.hasContradiction) return
|
||||
|
||||
candidate.system.processForkConstraints()
|
||||
|
||||
if (candidate.system.hasContradiction) {
|
||||
sink.yieldDiagnostic(candidate.system.errors.firstOrNull()?.let(::InferenceError) ?: InapplicableCandidate)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
@@ -125,4 +125,7 @@ object ConeConstraintSystemUtilContext : ConstraintSystemUtilContext {
|
||||
|
||||
override val isForcedConsiderExtensionReceiverFromConstrainsInLambda: Boolean
|
||||
get() = true
|
||||
|
||||
override val isForcedAllowForkingInferenceSystem: Boolean
|
||||
get() = true
|
||||
}
|
||||
|
||||
+2
@@ -50,6 +50,8 @@ class ConstraintSystemCompleter(private val components: BodyResolveComponents, p
|
||||
) = with(c) {
|
||||
val topLevelTypeVariables = candidateReturnType.extractTypeVariables()
|
||||
|
||||
c.processForkConstraints()
|
||||
|
||||
completion@ while (true) {
|
||||
val postponedArguments = getOrderedNotAnalyzedPostponedArguments(topLevelAtoms) // TODO: This is very slow
|
||||
|
||||
|
||||
Reference in New Issue
Block a user