diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/inference/builderInference.kt b/compiler/fir/analysis-tests/testData/resolveWithStdlib/inference/builderInference.kt new file mode 100644 index 00000000000..37b81062121 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/inference/builderInference.kt @@ -0,0 +1,10 @@ +fun foo(@BuilderInference block: MutableList.() -> Unit): T = null!! + +fun takeString(s: String) {} + +fun test() { + val s = foo { + this.add("") + } + takeString(s) +} \ No newline at end of file diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/inference/builderInference.txt b/compiler/fir/analysis-tests/testData/resolveWithStdlib/inference/builderInference.txt new file mode 100644 index 00000000000..f22324c775b --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/inference/builderInference.txt @@ -0,0 +1,13 @@ +FILE: builderInference.kt + public final fun foo(@R|kotlin/BuilderInference|() block: R|kotlin/collections/MutableList.() -> kotlin/Unit|): R|T| { + ^foo Null(null)!! + } + public final fun takeString(s: R|kotlin/String|): R|kotlin/Unit| { + } + public final fun test(): R|kotlin/Unit| { + lval s: R|kotlin/String| = R|/foo|( = foo@fun R|kotlin/collections/MutableList|.(): R|kotlin/Unit| { + ^ this@R|special/anonymous|.R|FakeOverride|(String()) + } + ) + R|/takeString|(R|/s|) + } diff --git a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithStdlibTestGenerated.java b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithStdlibTestGenerated.java index f1cac337d91..1c2b18f18e6 100644 --- a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithStdlibTestGenerated.java +++ b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithStdlibTestGenerated.java @@ -687,6 +687,11 @@ public class FirDiagnosticsWithStdlibTestGenerated extends AbstractFirDiagnostic KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolveWithStdlib/inference"), Pattern.compile("^([^.]+)\\.kt$"), null, true); } + @TestMetadata("builderInference.kt") + public void testBuilderInference() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/inference/builderInference.kt"); + } + @TestMetadata("complexConstraintSystem.kt") public void testComplexConstraintSystem() throws Exception { runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/inference/complexConstraintSystem.kt"); diff --git a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypeUtils.kt b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypeUtils.kt index bb2979e8454..5f0d909dc58 100644 --- a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypeUtils.kt +++ b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypeUtils.kt @@ -6,10 +6,31 @@ package org.jetbrains.kotlin.fir.types import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.utils.SmartSet import org.jetbrains.kotlin.utils.addToStdlib.safeAs val ConeKotlinType.isNullable: Boolean get() = nullability != ConeNullability.NOT_NULL val ConeKotlinType.isMarkedNullable: Boolean get() = nullability == ConeNullability.NULLABLE -val ConeKotlinType.classId: ClassId? get() = this.safeAs()?.lookupTag?.classId \ No newline at end of file +val ConeKotlinType.classId: ClassId? get() = this.safeAs()?.lookupTag?.classId + +fun ConeKotlinType.contains(predicate: (ConeKotlinType) -> Boolean): Boolean { + return contains(predicate, null) +} + +private fun ConeKotlinType.contains(predicate: (ConeKotlinType) -> Boolean, visited: SmartSet?): Boolean { + if (visited?.contains(this) == true) return false + if (predicate(this)) return true + + @Suppress("NAME_SHADOWING") + val visited = visited ?: SmartSet.create() + visited += this + + return when (this) { + is ConeFlexibleType -> lowerBound.contains(predicate, visited) || upperBound.contains(predicate, visited) + is ConeDefinitelyNotNullType -> original.contains(predicate, visited) + is ConeIntersectionType -> intersectedTypes.any { it.contains(predicate, visited) } + else -> typeArguments.any { it is ConeKotlinTypeProjection && it.type.contains(predicate, visited) } + } +} \ No newline at end of file diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallKind.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallKind.kt index 41357ccf21b..51fa103985d 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallKind.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallKind.kt @@ -14,7 +14,8 @@ enum class CallKind(vararg resolutionSequence: ResolutionStage) { CreateFreshTypeVariableSubstitutorStage, CheckReceivers.Dispatch, CheckReceivers.Extension, - CheckLowPriorityInOverloadResolution + CheckLowPriorityInOverloadResolution, + PostponedVariablesInitializerResolutionStage ), SyntheticSelect( MapArguments, @@ -34,7 +35,8 @@ enum class CallKind(vararg resolutionSequence: ResolutionStage) { CheckReceivers.Extension, CheckArguments, EagerResolveOfCallableReferences, - CheckLowPriorityInOverloadResolution + CheckLowPriorityInOverloadResolution, + PostponedVariablesInitializerResolutionStage ), DelegatingConstructorCall( CheckVisibility, diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt index 9b911720ff8..3bea732b00c 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt @@ -15,8 +15,7 @@ import org.jetbrains.kotlin.fir.inferenceContext import org.jetbrains.kotlin.fir.references.FirSuperReference import org.jetbrains.kotlin.fir.render import org.jetbrains.kotlin.fir.resolve.* -import org.jetbrains.kotlin.fir.resolve.inference.ResolvedCallableReferenceAtom -import org.jetbrains.kotlin.fir.resolve.inference.csBuilder +import org.jetbrains.kotlin.fir.resolve.inference.* import org.jetbrains.kotlin.fir.resolve.inference.extractInputOutputTypesFromCallableReferenceExpectedType import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol import org.jetbrains.kotlin.fir.symbols.SyntheticSymbol @@ -534,3 +533,35 @@ internal object CheckLowPriorityInOverloadResolution : CheckerStage() { } } } + +internal object PostponedVariablesInitializerResolutionStage : ResolutionStage() { + val BUILDER_INFERENCE_CLASS_ID: ClassId = ClassId.fromString("kotlin/BuilderInference") + + override suspend fun check(candidate: Candidate, sink: CheckerSink, callInfo: CallInfo) { + val argumentMapping = candidate.argumentMapping ?: return + // TODO: convert type argument mapping to map [FirTypeParameterSymbol, FirTypedProjection?] + if (candidate.typeArgumentMapping is TypeArgumentMapping.Mapped) return + for (parameter in argumentMapping.values) { + if (!parameter.hasBuilderInferenceMarker()) continue + val type = parameter.returnTypeRef.coneTypeSafe() ?: continue + val receiverType = type.receiverType(callInfo.session) ?: continue + + for (freshVariable in candidate.freshVariables) { + candidate.typeArgumentMapping + if (candidate.csBuilder.isPostponedTypeVariable(freshVariable)) continue + if (freshVariable !is TypeParameterBasedTypeVariable) continue + val typeParameterSymbol = freshVariable.typeParameterSymbol + val typeHasVariable = receiverType.contains { + (it as? ConeTypeParameterType)?.lookupTag?.typeParameterSymbol == typeParameterSymbol + } + if (typeHasVariable) { + candidate.csBuilder.markPostponedVariable(freshVariable) + } + } + } + } + + private fun FirValueParameter.hasBuilderInferenceMarker(): Boolean { + return this.hasAnnotation(BUILDER_INFERENCE_CLASS_ID) + } +} \ No newline at end of file diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/AbstractManyCandidatesInferenceSession.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/AbstractManyCandidatesInferenceSession.kt index a73d5579b4b..120e9840575 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/AbstractManyCandidatesInferenceSession.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/AbstractManyCandidatesInferenceSession.kt @@ -5,12 +5,10 @@ package org.jetbrains.kotlin.fir.resolve.inference -import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirResolvable import org.jetbrains.kotlin.fir.expressions.FirStatement import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents import org.jetbrains.kotlin.fir.resolve.calls.Candidate -import org.jetbrains.kotlin.fir.resolve.calls.FirNamedReferenceWithCandidate import org.jetbrains.kotlin.fir.resolve.calls.candidate import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor import org.jetbrains.kotlin.fir.types.ConeKotlinType @@ -19,50 +17,32 @@ import org.jetbrains.kotlin.resolve.calls.inference.NewConstraintSystem import org.jetbrains.kotlin.resolve.calls.inference.buildAbstractResultingSubstitutor import org.jetbrains.kotlin.resolve.calls.inference.components.KotlinConstraintSystemCompleter import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage -import org.jetbrains.kotlin.utils.addToStdlib.safeAs abstract class AbstractManyCandidatesInferenceSession( protected val components: BodyResolveComponents, - initialCall: FirExpression, private val postponedArgumentsAnalyzer: PostponedArgumentsAnalyzer, ) : FirInferenceSession() { private val errorCalls: MutableList = mutableListOf() - private val partiallyResolvedCalls: MutableList = mutableListOf() + protected val partiallyResolvedCalls: MutableList> = mutableListOf() private val completedCalls: MutableSet = mutableSetOf() - init { - val initialCandidate = (initialCall as? FirResolvable) - ?.calleeReference - ?.safeAs() - ?.candidate - if (initialCandidate != null) { - partiallyResolvedCalls += initialCall as FirResolvable - } - } - private val unitType: ConeKotlinType = components.session.builtinTypes.unitType.coneTypeUnsafe() override val currentConstraintSystem: ConstraintStorage get() = partiallyResolvedCalls.lastOrNull() - ?.calleeReference - ?.safeAs() - ?.candidate + ?.second ?.system ?.currentStorage() ?: ConstraintStorage.Empty private lateinit var resultingConstraintSystem: NewConstraintSystem - override fun shouldRunCompletion(candidate: Candidate): Boolean { - return false - } - - override fun addCompetedCall(call: T) where T : FirResolvable, T : FirStatement { + override fun addCompetedCall(call: T, candidate: Candidate) where T : FirResolvable, T : FirStatement { // do nothing } final override fun addPartiallyResolvedCall(call: T) where T : FirResolvable, T : FirStatement { - partiallyResolvedCalls += call + partiallyResolvedCalls += call to call.candidate } final override fun addErrorCall(call: T) where T : FirResolvable, T : FirStatement { @@ -97,7 +77,7 @@ abstract class AbstractManyCandidatesInferenceSession( } @Suppress("UNCHECKED_CAST") - val resolvedCalls = partiallyResolvedCalls as List + val resolvedCalls = partiallyResolvedCalls.map { it.first } val commonSystem = components.inferenceComponents.createConstraintSystem().apply { addOtherSystem(currentConstraintSystem) } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirBuilderInferenceSession.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirBuilderInferenceSession.kt new file mode 100644 index 00000000000..7a23b60456a --- /dev/null +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirBuilderInferenceSession.kt @@ -0,0 +1,220 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.fir.resolve.inference + +import org.jetbrains.kotlin.fir.expressions.FirResolvable +import org.jetbrains.kotlin.fir.expressions.FirStatement +import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents +import org.jetbrains.kotlin.fir.resolve.calls.Candidate +import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor +import org.jetbrains.kotlin.fir.resolve.transformers.FirCallCompletionResultsWriterTransformer +import org.jetbrains.kotlin.fir.types.ConeKotlinType +import org.jetbrains.kotlin.fir.types.ConeStubType +import org.jetbrains.kotlin.fir.types.ConeTypeVariable +import org.jetbrains.kotlin.fir.types.ConeTypeVariableTypeConstructor +import org.jetbrains.kotlin.fir.visitors.transformSingle +import org.jetbrains.kotlin.resolve.calls.inference.buildAbstractResultingSubstitutor +import org.jetbrains.kotlin.resolve.calls.inference.components.KotlinConstraintSystemCompleter +import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintKind +import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage +import org.jetbrains.kotlin.resolve.calls.inference.model.CoroutinePosition +import org.jetbrains.kotlin.resolve.calls.inference.model.NewConstraintSystemImpl +import org.jetbrains.kotlin.types.model.TypeConstructorMarker + +class FirBuilderInferenceSession( + components: BodyResolveComponents, + postponedArgumentsAnalyzer: PostponedArgumentsAnalyzer, + private val stubsForPostponedVariables: Map, +) : AbstractManyCandidatesInferenceSession(components, postponedArgumentsAnalyzer) { + private val commonCalls: MutableList> = mutableListOf() + + override fun shouldRunCompletion(call: T): Boolean where T : FirResolvable, T : FirStatement { + val candidate = call.candidate + val system = candidate.system + + if (system.hasContradiction) return true + + val storage = system.getBuilder().currentStorage() + + return !storage.notFixedTypeVariables.keys.any { + val variable = storage.allTypeVariables[it] + val isPostponed = variable != null && variable in storage.postponedTypeVariables + !isPostponed && !components.callCompleter.completer.variableFixationFinder.isTypeVariableHasProperConstraint(system, it) + } || call.hasPostponed() + } + + private fun FirStatement.hasPostponed(): Boolean { + var result = false + processAllContainingCallCandidates(processBlocks = false) { + result = result || it.hasPostponed() + } + return result + } + + private fun Candidate.hasPostponed(): Boolean { + return postponedAtoms.any { !it.analyzed } + } + + override fun addCompetedCall(call: T, candidate: Candidate) where T : FirResolvable, T : FirStatement { + if (skipCall(call)) return + commonCalls += call to candidate + } + + override fun writeOnlyStubs(call: T): Boolean where T : FirResolvable, T : FirStatement { + return !skipCall(call) + } + + private fun skipCall(call: T): Boolean where T : FirResolvable, T : FirStatement { + // TODO: what is FIR analog? + // if (descriptor is FakeCallableDescriptorForObject) return true + // if (!DescriptorUtils.isObject(descriptor) && isInLHSOfDoubleColonExpression(callInfo)) return true + + return false + } + + override val currentConstraintSystem: ConstraintStorage + get() = ConstraintStorage.Empty + + override fun shouldCompleteResolvedSubAtomsOf(call: T): Boolean where T : FirResolvable, T : FirStatement { + return true + } + + override fun inferPostponedVariables( + lambda: ResolvedLambdaAtom, + initialStorage: ConstraintStorage + ): Map? { + val (commonSystem, effectivelyEmptyConstraintSystem) = buildCommonSystem(initialStorage) + if (effectivelyEmptyConstraintSystem) { + updateCalls(commonSystem, lambda) + return null + } + + val context = commonSystem.asConstraintSystemCompleterContext() + @Suppress("UNCHECKED_CAST") + components.callCompleter.completer.complete( + context, + KotlinConstraintSystemCompleter.ConstraintSystemCompletionMode.FULL, + partiallyResolvedCalls.map { it.first as FirStatement }, + components.session.builtinTypes.unitType.type, + collectVariablesFromContext = true + ) { + error("Shouldn't be called in complete constraint system mode") + } + + updateCalls(commonSystem, lambda) + + @Suppress("UNCHECKED_CAST") + return commonSystem.fixedTypeVariables as Map + } + + private fun buildCommonSystem(initialStorage: ConstraintStorage): Pair { + val commonSystem = components.inferenceComponents.createConstraintSystem() + val nonFixedToVariablesSubstitutor = createNonFixedTypeToVariableSubstitutor() + + integrateConstraints(commonSystem, initialStorage, nonFixedToVariablesSubstitutor, false) + + var effectivelyEmptyCommonSystem = true + + for ((_, candidate) in commonCalls) { + val hasConstraints = + integrateConstraints(commonSystem, candidate.system.asReadOnlyStorage(), nonFixedToVariablesSubstitutor, false) + if (hasConstraints) effectivelyEmptyCommonSystem = false + } + for ((_, candidate) in partiallyResolvedCalls) { + val hasConstraints = + integrateConstraints(commonSystem, candidate.system.asReadOnlyStorage(), nonFixedToVariablesSubstitutor, true) + if (hasConstraints) effectivelyEmptyCommonSystem = false + } + + // TODO: add diagnostics holder +// for (diagnostic in diagnostics) { +// commonSystem.addError(diagnostic) +// } + + return commonSystem to effectivelyEmptyCommonSystem + } + + private fun createNonFixedTypeToVariableSubstitutor(): ConeSubstitutor { + val ctx = components.inferenceComponents.ctx + + val bindings = mutableMapOf() + for ((variable, nonFixedType) in stubsForPostponedVariables) { + bindings[nonFixedType.variable.typeConstructor] = variable.defaultType + } + + return ctx.typeSubstitutorByTypeConstructor(bindings) + } + + private fun integrateConstraints( + commonSystem: NewConstraintSystemImpl, + storage: ConstraintStorage, + nonFixedToVariablesSubstitutor: ConeSubstitutor, + shouldIntegrateAllConstraints: Boolean + ): Boolean { + storage.notFixedTypeVariables.values.forEach { commonSystem.registerVariable(it.typeVariable) } + + /* + * storage can contain the following substitutions: + * TypeVariable(A) -> ProperType + * TypeVariable(B) -> Special-Non-Fixed-Type + * + * while substitutor from parameter map non-fixed types to the original type variable + * */ + val callSubstitutor = storage.buildAbstractResultingSubstitutor(commonSystem, transformTypeVariablesToErrorTypes = false) as ConeSubstitutor + + var introducedConstraint = false + + for (initialConstraint in storage.initialConstraints) { + val lower = nonFixedToVariablesSubstitutor.substituteOrSelf(callSubstitutor.substituteOrSelf(initialConstraint.a as ConeKotlinType)) // TODO: SUB + val upper = nonFixedToVariablesSubstitutor.substituteOrSelf(callSubstitutor.substituteOrSelf(initialConstraint.b as ConeKotlinType)) // TODO: SUB + + if (commonSystem.isProperType(lower) && commonSystem.isProperType(upper)) continue + + introducedConstraint = true + + when (initialConstraint.constraintKind) { + ConstraintKind.LOWER -> error("LOWER constraint shouldn't be used, please use UPPER") + + ConstraintKind.UPPER -> commonSystem.addSubtypeConstraint(lower, upper, initialConstraint.position) + + ConstraintKind.EQUALITY -> + with(commonSystem) { + addSubtypeConstraint(lower, upper, initialConstraint.position) + addSubtypeConstraint(upper, lower, initialConstraint.position) + } + } + } + + if (shouldIntegrateAllConstraints) { + for ((variableConstructor, type) in storage.fixedTypeVariables) { + val typeVariable = storage.allTypeVariables.getValue(variableConstructor) + commonSystem.registerVariable(typeVariable) + commonSystem.addEqualityConstraint((typeVariable as ConeTypeVariable).defaultType, type, CoroutinePosition()) + introducedConstraint = true + } + } + + return introducedConstraint + } + + private fun updateCalls(commonSystem: NewConstraintSystemImpl, lambda: ResolvedLambdaAtom) { + val nonFixedToVariablesSubstitutor = createNonFixedTypeToVariableSubstitutor() + val commonSystemSubstitutor = commonSystem.buildCurrentSubstitutor() as ConeSubstitutor + val nonFixedTypesToResultSubstitutor = ConeComposedSubstitutor(commonSystemSubstitutor, nonFixedToVariablesSubstitutor) + val completionResultsWriter = components.callCompleter.createCompletionResultsWriter(nonFixedTypesToResultSubstitutor) + for ((call, _) in partiallyResolvedCalls) { + call.transformSingle(completionResultsWriter, null) + // TODO: support diagnostics, see CoroutineInferenceSession.kt:286 + } + } +} + +class ConeComposedSubstitutor(val left: ConeSubstitutor, val right: ConeSubstitutor) : ConeSubstitutor() { + override fun substituteOrNull(type: ConeKotlinType): ConeKotlinType? { + val rightSubstitution = right.substituteOrNull(type) + return left.substituteOrNull(rightSubstitution ?: type) + } +} diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirCallCompleter.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirCallCompleter.kt index 4321d5a139d..a1785231b8d 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirCallCompleter.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirCallCompleter.kt @@ -9,13 +9,11 @@ import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin import org.jetbrains.kotlin.fir.declarations.builder.buildValueParameter import org.jetbrains.kotlin.fir.expressions.FirExpression -import org.jetbrains.kotlin.fir.expressions.FirFunctionCall import org.jetbrains.kotlin.fir.expressions.FirResolvable import org.jetbrains.kotlin.fir.expressions.FirStatement import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents import org.jetbrains.kotlin.fir.resolve.ResolutionMode import org.jetbrains.kotlin.fir.resolve.calls.FirNamedReferenceWithCandidate -import org.jetbrains.kotlin.fir.resolve.calls.candidate import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor import org.jetbrains.kotlin.fir.resolve.transformers.FirCallCompletionResultsWriterTransformer import org.jetbrains.kotlin.fir.resolve.transformers.InvocationKindTransformer @@ -25,10 +23,7 @@ import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType import org.jetbrains.kotlin.fir.resolve.typeFromCallee import org.jetbrains.kotlin.fir.resolvedTypeFromPrototype import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol -import org.jetbrains.kotlin.fir.types.ConeKotlinErrorType -import org.jetbrains.kotlin.fir.types.ConeKotlinType -import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef -import org.jetbrains.kotlin.fir.types.FirTypeRef +import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef import org.jetbrains.kotlin.fir.visitors.transformSingle import org.jetbrains.kotlin.name.Name @@ -38,10 +33,11 @@ import org.jetbrains.kotlin.resolve.calls.inference.model.SimpleConstraintSystem import org.jetbrains.kotlin.types.TypeApproximatorConfiguration import org.jetbrains.kotlin.types.model.StubTypeMarker import org.jetbrains.kotlin.types.model.TypeVariableMarker +import org.jetbrains.kotlin.utils.addToStdlib.runIf class FirCallCompleter( private val transformer: FirBodyResolveTransformer, - components: FirAbstractBodyResolveTransformer.BodyResolveTransformerComponents + private val components: FirAbstractBodyResolveTransformer.BodyResolveTransformerComponents ) : BodyResolveComponents by components { val completer = ConstraintSystemCompleter(components) private val inferenceSession @@ -74,7 +70,7 @@ class FirCallCompleter( return when (completionMode) { ConstraintSystemCompletionMode.FULL -> { - if (inferenceSession.shouldRunCompletion(candidate)) { + if (inferenceSession.shouldRunCompletion(call)) { completer.complete(candidate.system.asConstraintSystemCompleterContext(), completionMode, listOf(call), initialType) { analyzer.analyze(candidate.system.asPostponedArgumentsAnalyzerContext(), it, candidate) } @@ -89,7 +85,7 @@ class FirCallCompleter( ), null ) - inferenceSession.addCompetedCall(completedCall) + inferenceSession.addCompetedCall(completedCall, candidate) CompletionResult(completedCall, true) } else { inferenceSession.addPartiallyResolvedCall(call) @@ -124,13 +120,22 @@ class FirCallCompleter( } fun createPostponedArgumentsAnalyzer(): PostponedArgumentsAnalyzer { + val lambdaAnalyzer = LambdaAnalyzerImpl() return PostponedArgumentsAnalyzer( - LambdaAnalyzerImpl(), inferenceComponents, + lambdaAnalyzer, inferenceComponents, transformer.components.callResolver - ) + ).also { + lambdaAnalyzer.initAnalyzer(it) + } } private inner class LambdaAnalyzerImpl : LambdaAnalyzer { + private lateinit var postponedArgumentsAnalyzer: PostponedArgumentsAnalyzer + + fun initAnalyzer(postponedArgumentsAnalyzer: PostponedArgumentsAnalyzer) { + this.postponedArgumentsAnalyzer = postponedArgumentsAnalyzer + } + override fun analyzeAndGetLambdaReturnArguments( lambdaAtom: ResolvedLambdaAtom, receiverType: ConeKotlinType?, @@ -178,16 +183,26 @@ class FirCallCompleter( lambdaArgument.replaceValueParameters(lambdaArgument.valueParameters + listOfNotNull(itParam)) lambdaArgument.replaceReturnTypeRef(expectedReturnTypeRef ?: noExpectedType) + val builderInferenceSession = runIf(stubsForPostponedVariables.isNotEmpty()) { + @Suppress("UNCHECKED_CAST") + FirBuilderInferenceSession(components, postponedArgumentsAnalyzer, stubsForPostponedVariables as Map) + } + val localContext = towerDataContextForAnonymousFunctions.getValue(lambdaArgument.symbol) transformer.context.withTowerDataContext(localContext) { - lambdaArgument.transformSingle(transformer, ResolutionMode.LambdaResolution(expectedReturnTypeRef)) + if (builderInferenceSession != null) { + components.inferenceComponents.withInferenceSession(builderInferenceSession) { + lambdaArgument.transformSingle(transformer, ResolutionMode.LambdaResolution(expectedReturnTypeRef)) + } + } else { + lambdaArgument.transformSingle(transformer, ResolutionMode.LambdaResolution(expectedReturnTypeRef)) + } } transformer.context.dropContextForAnonymousFunction(lambdaArgument) val returnArguments = dataFlowAnalyzer.returnExpressionsOfAnonymousFunction(lambdaArgument) - // TODO: add detecting of coroutine inference session - return ReturnArgumentsAnalysisResult(returnArguments, null) + return ReturnArgumentsAnalysisResult(returnArguments, builderInferenceSession) } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirDelegatedPropertyInferenceSession.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirDelegatedPropertyInferenceSession.kt index 59d5e6cb2db..e8744fca07c 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirDelegatedPropertyInferenceSession.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirDelegatedPropertyInferenceSession.kt @@ -15,6 +15,7 @@ import org.jetbrains.kotlin.fir.expressions.FirStatement import org.jetbrains.kotlin.fir.references.FirNamedReference import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents import org.jetbrains.kotlin.fir.resolve.calls.Candidate +import org.jetbrains.kotlin.fir.resolve.calls.FirNamedReferenceWithCandidate import org.jetbrains.kotlin.fir.resolve.defaultType import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol import org.jetbrains.kotlin.fir.types.ConeKotlinType @@ -26,19 +27,32 @@ import org.jetbrains.kotlin.resolve.calls.inference.NewConstraintSystem import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage import org.jetbrains.kotlin.resolve.calls.inference.model.SimpleConstraintSystemConstraintPosition import org.jetbrains.kotlin.util.OperatorNameConventions +import org.jetbrains.kotlin.utils.addToStdlib.safeAs class FirDelegatedPropertyInferenceSession( val property: FirProperty, initialCall: FirExpression, components: BodyResolveComponents, postponedArgumentsAnalyzer: PostponedArgumentsAnalyzer, -) : AbstractManyCandidatesInferenceSession(components, initialCall, postponedArgumentsAnalyzer) { +) : AbstractManyCandidatesInferenceSession(components, postponedArgumentsAnalyzer) { + init { + val initialCandidate = (initialCall as? FirResolvable) + ?.calleeReference + ?.safeAs() + ?.candidate + if (initialCandidate != null) { + addPartiallyResolvedCall(initialCall) + } + } + val expectedType: ConeKotlinType? by lazy { property.returnTypeRef.coneTypeSafe() } + override fun shouldRunCompletion(call: T): Boolean where T : FirResolvable, T : FirStatement = false + override fun inferPostponedVariables( lambda: ResolvedLambdaAtom, initialStorage: ConstraintStorage - ): Map = emptyMap() + ): Map? = null override fun shouldCompleteResolvedSubAtomsOf(call: T): Boolean where T : FirResolvable, T : FirStatement = true @@ -89,4 +103,6 @@ class FirDelegatedPropertyInferenceSession( val substitutedType = substitutor.substituteOrSelf(valueParameterForThis.returnTypeRef.coneTypeUnsafe()) commonSystem.addSubtypeConstraint(typeOfThis, substitutedType, SimpleConstraintSystemConstraintPosition) } + + override fun writeOnlyStubs(call: T): Boolean where T : FirResolvable, T : FirStatement = false } \ No newline at end of file diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirInferenceSession.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirInferenceSession.kt index 0af043c503a..70d163a2ad7 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirInferenceSession.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirInferenceSession.kt @@ -15,40 +15,40 @@ import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage abstract class FirInferenceSession { companion object { val DEFAULT: FirInferenceSession = object : FirInferenceSession() { - override fun shouldRunCompletion(candidate: Candidate): Boolean = true + override fun shouldRunCompletion(call: T): Boolean where T : FirResolvable, T : FirStatement = true override val currentConstraintSystem: ConstraintStorage get() = ConstraintStorage.Empty override fun addPartiallyResolvedCall(call: T) where T : FirResolvable, T : FirStatement {} override fun addErrorCall(call: T) where T : FirResolvable, T : FirStatement {} - override fun addCompetedCall(call: T) where T : FirResolvable, T : FirStatement {} + override fun addCompetedCall(call: T, candidate: Candidate) where T : FirResolvable, T : FirStatement {} override fun inferPostponedVariables( lambda: ResolvedLambdaAtom, initialStorage: ConstraintStorage - ): Map = emptyMap() + ): Map? = null + override fun writeOnlyStubs(call: T): Boolean where T : FirResolvable, T : FirStatement = false override fun callCompleted(call: T): Boolean where T : FirResolvable, T : FirStatement = false override fun shouldCompleteResolvedSubAtomsOf(call: T): Boolean where T : FirResolvable, T : FirStatement = true } } - abstract fun shouldRunCompletion(candidate: Candidate): Boolean + abstract fun shouldRunCompletion(call: T): Boolean where T : FirResolvable, T : FirStatement abstract val currentConstraintSystem: ConstraintStorage abstract fun addPartiallyResolvedCall(call: T) where T : FirResolvable, T : FirStatement abstract fun addErrorCall(call: T) where T : FirResolvable, T : FirStatement - abstract fun addCompetedCall(call: T) where T : FirResolvable, T : FirStatement + abstract fun addCompetedCall(call: T, candidate: Candidate) where T : FirResolvable, T : FirStatement abstract fun inferPostponedVariables( lambda: ResolvedLambdaAtom, initialStorage: ConstraintStorage, // TODO: diagnostic holder - ): Map + ): Map? -// TODO: do we need this? -// abstract fun writeOnlyStubs(): Boolean + abstract fun writeOnlyStubs(call: T): Boolean where T : FirResolvable, T : FirStatement abstract fun callCompleted(call: T): Boolean where T : FirResolvable, T : FirStatement abstract fun shouldCompleteResolvedSubAtomsOf(call: T): Boolean where T : FirResolvable, T : FirStatement } \ No newline at end of file diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/InferenceCompletion.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/InferenceCompletion.kt index 5f6b6cd5eb7..f6aac35b3e5 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/InferenceCompletion.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/InferenceCompletion.kt @@ -31,20 +31,21 @@ val Candidate.csBuilder: NewConstraintSystemImpl get() = system.getBuilder() class ConstraintSystemCompleter(private val components: BodyResolveComponents) { - private val variableFixationFinder = VariableFixationFinder(components.inferenceComponents.trivialConstraintTypeInferenceOracle) + val variableFixationFinder = VariableFixationFinder(components.inferenceComponents.trivialConstraintTypeInferenceOracle) fun complete( c: KotlinConstraintSystemCompleter.Context, completionMode: ConstraintSystemCompletionMode, topLevelAtoms: List, candidateReturnType: ConeKotlinType, + collectVariablesFromContext: Boolean = false, analyze: (PostponedResolvedAtom) -> Unit ) { while (true) { if (analyzePostponeArgumentIfPossible(c, topLevelAtoms, analyze)) continue - val allTypeVariables = getOrderedAllTypeVariables(c, topLevelAtoms) + val allTypeVariables = getOrderedAllTypeVariables(c, topLevelAtoms, collectVariablesFromContext) val postponedAtoms = getOrderedNotAnalyzedPostponedArguments(topLevelAtoms) val variableForFixation = variableFixationFinder.findFirstVariableForFixation( @@ -167,8 +168,12 @@ class ConstraintSystemCompleter(private val components: BodyResolveComponents) { private fun getOrderedAllTypeVariables( c: KotlinConstraintSystemCompleter.Context, - topLevelAtoms: List + topLevelAtoms: List, + collectVariablesFromContext: Boolean ): List { + if (collectVariablesFromContext) { + return c.notFixedTypeVariables.keys.toList() + } val result = LinkedHashSet(c.notFixedTypeVariables.size) fun ConeTypeVariable?.toTypeConstructor(): TypeConstructorMarker? = this?.typeConstructor?.takeIf { it in c.notFixedTypeVariables.keys } @@ -179,14 +184,11 @@ class ConstraintSystemCompleter(private val components: BodyResolveComponents) { typeVariable.toTypeConstructor() } - for (postponedAtom in candidate.postponedAtoms) { - when (postponedAtom) { - is ResolvedLambdaAtom -> postponedAtom.typeVariableForLambdaReturnType + for (lambdaAtom in candidate.postponedAtoms) { + if (lambdaAtom is ResolvedLambdaAtom) { + result.addIfNotNull(lambdaAtom.typeVariableForLambdaReturnType.toTypeConstructor()) } } - for (lambdaAtom in candidate.postponedAtoms.filterIsInstance()) { - result.addIfNotNull(lambdaAtom.typeVariableForLambdaReturnType.toTypeConstructor()) - } } } @@ -252,76 +254,74 @@ class ConstraintSystemCompleter(private val components: BodyResolveComponents) { return notAnalyzedArguments } - private fun FirStatement.processAllContainingCallCandidates(processBlocks: Boolean, processor: (Candidate) -> Unit) { - when (this) { - is FirFunctionCall -> { - processCandidateIfApplicable(processor, processBlocks) - this.arguments.forEach { it.processAllContainingCallCandidates(processBlocks, processor) } - } - - is FirSafeCallExpression -> { - this.regularQualifiedAccess.processAllContainingCallCandidates(processBlocks, processor) - } - - is FirWhenExpression -> { - processCandidateIfApplicable(processor, processBlocks) - this.branches.forEach { it.result.processAllContainingCallCandidates(processBlocks, processor) } - } - - is FirTryExpression -> { - processCandidateIfApplicable(processor, processBlocks) - tryBlock.processAllContainingCallCandidates(processBlocks, processor) - catches.forEach { it.block.processAllContainingCallCandidates(processBlocks, processor) } - } - - is FirCheckNotNullCall -> { - processCandidateIfApplicable(processor, processBlocks) - this.arguments.forEach { it.processAllContainingCallCandidates(processBlocks, processor) } - } - - is FirQualifiedAccessExpression -> { - processCandidateIfApplicable(processor, processBlocks) - } - - is FirVariableAssignment -> { - processCandidateIfApplicable(processor, processBlocks) - rValue.processAllContainingCallCandidates(processBlocks, processor) - } - - is FirWrappedArgumentExpression -> this.expression.processAllContainingCallCandidates(processBlocks, processor) - is FirBlock -> { - if (processBlocks) { - this.returnExpressions().forEach { it.processAllContainingCallCandidates(processBlocks, processor) } - } - } - - is FirDelegatedConstructorCall -> { - processCandidateIfApplicable(processor, processBlocks) - this.arguments.forEach { it.processAllContainingCallCandidates(processBlocks, processor) } - } - } - } - - private fun FirResolvable.processCandidateIfApplicable( - processor: (Candidate) -> Unit, - processBlocks: Boolean - ) { - val candidate = (calleeReference as? FirNamedReferenceWithCandidate)?.candidate ?: return - processor(candidate) - - for (atom in candidate.postponedAtoms) { - if (atom !is ResolvedLambdaAtom || !atom.analyzed) continue - - atom.returnStatements.forEach { - it.processAllContainingCallCandidates(processBlocks, processor) - } - } - } - private fun canWeAnalyzeIt(c: KotlinConstraintSystemCompleter.Context, argument: PostponedResolvedAtomMarker): Boolean { if (argument.analyzed) return false - return argument.inputTypes.all { c.containsOnlyFixedOrPostponedVariables(it) } } - +} + +fun FirStatement.processAllContainingCallCandidates(processBlocks: Boolean, processor: (Candidate) -> Unit) { + when (this) { + is FirFunctionCall -> { + processCandidateIfApplicable(processor, processBlocks) + this.arguments.forEach { it.processAllContainingCallCandidates(processBlocks, processor) } + } + + is FirSafeCallExpression -> { + this.regularQualifiedAccess.processAllContainingCallCandidates(processBlocks, processor) + } + + is FirWhenExpression -> { + processCandidateIfApplicable(processor, processBlocks) + this.branches.forEach { it.result.processAllContainingCallCandidates(processBlocks, processor) } + } + + is FirTryExpression -> { + processCandidateIfApplicable(processor, processBlocks) + tryBlock.processAllContainingCallCandidates(processBlocks, processor) + catches.forEach { it.block.processAllContainingCallCandidates(processBlocks, processor) } + } + + is FirCheckNotNullCall -> { + processCandidateIfApplicable(processor, processBlocks) + this.arguments.forEach { it.processAllContainingCallCandidates(processBlocks, processor) } + } + + is FirQualifiedAccessExpression -> { + processCandidateIfApplicable(processor, processBlocks) + } + + is FirVariableAssignment -> { + processCandidateIfApplicable(processor, processBlocks) + rValue.processAllContainingCallCandidates(processBlocks, processor) + } + + is FirWrappedArgumentExpression -> this.expression.processAllContainingCallCandidates(processBlocks, processor) + is FirBlock -> { + if (processBlocks) { + this.returnExpressions().forEach { it.processAllContainingCallCandidates(processBlocks, processor) } + } + } + + is FirDelegatedConstructorCall -> { + processCandidateIfApplicable(processor, processBlocks) + this.arguments.forEach { it.processAllContainingCallCandidates(processBlocks, processor) } + } + } +} + +private fun FirResolvable.processCandidateIfApplicable( + processor: (Candidate) -> Unit, + processBlocks: Boolean +) { + val candidate = (calleeReference as? FirNamedReferenceWithCandidate)?.candidate ?: return + processor(candidate) + + for (atom in candidate.postponedAtoms) { + if (atom !is ResolvedLambdaAtom || !atom.analyzed) continue + + atom.returnStatements.forEach { + it.processAllContainingCallCandidates(processBlocks, processor) + } + } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/InferenceUtils.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/InferenceUtils.kt index ebe7a9f0b02..85918520d29 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/InferenceUtils.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/InferenceUtils.kt @@ -45,6 +45,13 @@ fun ConeKotlinType.receiverType(expectedTypeRef: FirTypeRef?, session: FirSessio return null } +fun ConeKotlinType.receiverType(session: FirSession): ConeKotlinType? { + if (isBuiltinFunctionalType(session)) { + return ((this as ConeClassLikeType).fullyExpandedType(session).typeArguments.first() as ConeKotlinTypeProjection).type + } + return null +} + fun ConeKotlinType.returnType(session: FirSession): ConeKotlinType? { require(this is ConeClassLikeType) val projection = fullyExpandedType(session).typeArguments.last() diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/PostponedArgumentsAnalyzer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/PostponedArgumentsAnalyzer.kt index 9120c2f9619..095f90b5a43 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/PostponedArgumentsAnalyzer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/PostponedArgumentsAnalyzer.kt @@ -130,6 +130,24 @@ class PostponedArgumentsAnalyzer( stubsForPostponedVariables ) + if (inferenceSession != null) { + val storageSnapshot = c.getBuilder().currentStorage() + + val postponedVariables = inferenceSession.inferPostponedVariables(lambda, storageSnapshot) + + if (postponedVariables == null) { + c.getBuilder().removePostponedVariables() + } else { + for ((constructor, resultType) in postponedVariables) { + val variableWithConstraints = storageSnapshot.notFixedTypeVariables[constructor] ?: continue + val variable = variableWithConstraints.typeVariable as ConeTypeVariable + + c.getBuilder().unmarkPostponedVariable(variable) + c.getBuilder().addEqualityConstraint(variable.defaultType, resultType, CoroutinePosition()) + } + } + } + returnArguments.forEach { c.addSubsystemFromExpression(it) } val checkerSink: CheckerSink = CheckerSinkImpl(components) @@ -157,20 +175,6 @@ class PostponedArgumentsAnalyzer( lambda.analyzed = true lambda.returnStatements = returnArguments - - if (inferenceSession != null) { - val storageSnapshot = c.getBuilder().currentStorage() - - val postponedVariables = inferenceSession.inferPostponedVariables(lambda, storageSnapshot) - - for ((constructor, resultType) in postponedVariables) { - val variableWithConstraints = storageSnapshot.notFixedTypeVariables[constructor] ?: continue - val variable = variableWithConstraints.typeVariable as ConeTypeVariable - - c.getBuilder().unmarkPostponedVariable(variable) - c.getBuilder().addEqualityConstraint(variable.defaultType, resultType, CoroutinePosition()) - } - } } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirCallCompletionResultsWriterTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirCallCompletionResultsWriterTransformer.kt index 8b2615aeaac..34578bc6981 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirCallCompletionResultsWriterTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirCallCompletionResultsWriterTransformer.kt @@ -371,20 +371,31 @@ class FirCallCompletionResultsWriterTransformer( data: ExpectedArgumentType?, ): CompositeTransformResult { val expectedType = data?.getExpectedType(anonymousFunction)?.takeIf { it.isBuiltinFunctionalType(session) } - val expectedReturnType = expectedType?.returnType(session) as? ConeClassLikeType + var needUpdateLambdaType = false + + val initialReceiverType = anonymousFunction.receiverTypeRef?.coneTypeSafe() + val resultReceiverType = initialReceiverType?.let { finalSubstitutor.substituteOrNull(it) } + if (resultReceiverType != null) { + anonymousFunction.replaceReceiverTypeRef(anonymousFunction.receiverTypeRef!!.resolvedTypeFromPrototype(resultReceiverType)) + needUpdateLambdaType = true + } + + val expectedReturnType = expectedType?.returnType(session) as? ConeClassLikeType val initialType = anonymousFunction.returnTypeRef.coneTypeSafe() if (initialType != null) { val finalType = expectedReturnType ?: finalSubstitutor.substituteOrNull(initialType) - val resultType = anonymousFunction.returnTypeRef.withReplacedConeType(finalType) - anonymousFunction.transformReturnTypeRef(StoreType, resultType) + needUpdateLambdaType = true + } + if (needUpdateLambdaType) { anonymousFunction.replaceTypeRef( anonymousFunction.constructFunctionalTypeRef(session, isSuspend = expectedType?.isSuspendFunctionType(session) == true) ) } + val result = transformElement(anonymousFunction, null) val resultFunction = result.single if (resultFunction.returnTypeRef.coneTypeSafe() != null) { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeInferenceContext.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeInferenceContext.kt index 8aa73e11c94..b743d744c45 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeInferenceContext.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeInferenceContext.kt @@ -295,19 +295,19 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo return this.original as SimpleTypeMarker } - override fun typeSubstitutorByTypeConstructor(map: Map): TypeSubstitutorMarker { + override fun typeSubstitutorByTypeConstructor(map: Map): ConeSubstitutor { if (map.isEmpty()) return createEmptySubstitutor() return object : AbstractConeSubstitutor(), TypeSubstitutorMarker { override fun substituteType(type: ConeKotlinType): ConeKotlinType? { - if (type !is ConeLookupTagBasedType) return null + if (type !is ConeLookupTagBasedType && type !is ConeStubType) return null val new = map[type.typeConstructor()] ?: return null return (new as ConeKotlinType).approximateIntegerLiteralType().updateNullabilityIfNeeded(type) } } } - override fun createEmptySubstitutor(): TypeSubstitutorMarker { + override fun createEmptySubstitutor(): ConeSubstitutor { return ConeSubstitutor.Empty } diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/FirDeclarationUtil.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/FirDeclarationUtil.kt index a62b347a5d2..9ff689c003a 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/FirDeclarationUtil.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/FirDeclarationUtil.kt @@ -14,10 +14,9 @@ import org.jetbrains.kotlin.fir.declarations.impl.FirFileImpl import org.jetbrains.kotlin.fir.symbols.impl.FirAnonymousObjectSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol -import org.jetbrains.kotlin.fir.types.ConeClassLikeType -import org.jetbrains.kotlin.fir.types.ConeFlexibleType +import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef -import org.jetbrains.kotlin.fir.types.coneTypeSafe +import org.jetbrains.kotlin.name.ClassId fun FirTypeParameterBuilder.addDefaultBoundIfNecessary(isFlexible: Boolean = false) { if (bounds.isEmpty()) { @@ -114,3 +113,7 @@ fun FirRegularClass.addDeclaration(declaration: FirDeclaration) { private object IsFromVarargKey: FirDeclarationDataKey() var FirProperty.isFromVararg: Boolean? by FirDeclarationDataRegistry.data(IsFromVarargKey) + +fun FirAnnotatedDeclaration.hasAnnotation(classId: ClassId): Boolean { + return annotations.any { it.annotationTypeRef.coneTypeSafe()?.classId == classId } +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/coroutines/asyncIteratorNullMerge_1_3.kt b/compiler/testData/codegen/box/coroutines/asyncIteratorNullMerge_1_3.kt index e0b252392c9..dccde410487 100644 --- a/compiler/testData/codegen/box/coroutines/asyncIteratorNullMerge_1_3.kt +++ b/compiler/testData/codegen/box/coroutines/asyncIteratorNullMerge_1_3.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // WITH_RUNTIME // WITH_COROUTINES diff --git a/compiler/testData/codegen/box/coroutines/asyncIteratorToList_1_3.kt b/compiler/testData/codegen/box/coroutines/asyncIteratorToList_1_3.kt index 00e64d050f7..e3c15ab185e 100644 --- a/compiler/testData/codegen/box/coroutines/asyncIteratorToList_1_3.kt +++ b/compiler/testData/codegen/box/coroutines/asyncIteratorToList_1_3.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // KJS_WITH_FULL_RUNTIME // WITH_RUNTIME // WITH_COROUTINES diff --git a/compiler/testData/codegen/box/coroutines/asyncIterator_1_3.kt b/compiler/testData/codegen/box/coroutines/asyncIterator_1_3.kt index 22b9748e909..47ae87c68af 100644 --- a/compiler/testData/codegen/box/coroutines/asyncIterator_1_3.kt +++ b/compiler/testData/codegen/box/coroutines/asyncIterator_1_3.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // WITH_RUNTIME // WITH_COROUTINES diff --git a/compiler/testData/codegen/box/coroutines/emptyCommonConstraintSystemForCoroutineInferenceCall.kt b/compiler/testData/codegen/box/coroutines/emptyCommonConstraintSystemForCoroutineInferenceCall.kt index 0b3cd9a4762..cf04023657c 100644 --- a/compiler/testData/codegen/box/coroutines/emptyCommonConstraintSystemForCoroutineInferenceCall.kt +++ b/compiler/testData/codegen/box/coroutines/emptyCommonConstraintSystemForCoroutineInferenceCall.kt @@ -1,7 +1,6 @@ // WITH_RUNTIME // WITH_COROUTINES // KJS_WITH_FULL_RUNTIME -// IGNORE_BACKEND_FIR: JVM_IR import helpers.* import kotlin.coroutines.* diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/coroutineInferenceWithCapturedTypeVariable.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/coroutineInferenceWithCapturedTypeVariable.fir.kt deleted file mode 100644 index dacc9396e43..00000000000 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/coroutineInferenceWithCapturedTypeVariable.fir.kt +++ /dev/null @@ -1,19 +0,0 @@ -// !LANGUAGE: +NewInference -// !DIAGNOSTICS: -UNUSED_PARAMETER -// !USE_EXPERIMENTAL: kotlin.RequiresOptIn - -import kotlin.experimental.ExperimentalTypeInference - -suspend fun main() { - iFlow { emit(1) } -} - - -@OptIn(ExperimentalTypeInference::class) -fun iFlow(@BuilderInference block: suspend iFlowCollector.() -> Unit): iFlow = TODO() - -interface iFlowCollector { - suspend fun emit(value: S) -} - -interface iFlow \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/coroutineInferenceWithCapturedTypeVariable.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/coroutineInferenceWithCapturedTypeVariable.kt index 457eef3a633..417d9f64b11 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/coroutineInferenceWithCapturedTypeVariable.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/coroutineInferenceWithCapturedTypeVariable.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !LANGUAGE: +NewInference // !DIAGNOSTICS: -UNUSED_PARAMETER // !USE_EXPERIMENTAL: kotlin.RequiresOptIn diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/correctMember.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/correctMember.fir.kt deleted file mode 100644 index 1ca70df48f9..00000000000 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/correctMember.fir.kt +++ /dev/null @@ -1,25 +0,0 @@ -// !USE_EXPERIMENTAL: kotlin.RequiresOptIn -// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE - -@file:OptIn(ExperimentalTypeInference::class) - -import kotlin.experimental.ExperimentalTypeInference - -interface Controller { - suspend fun yield(t: T) {} - - fun justString(): String = "" - - fun generidFun(t: Z) = t -} - -fun generate(@BuilderInference g: suspend Controller.() -> Unit): S = TODO() - -val test1 = generate { - yield(justString()) -} - -val test2 = generate { - yield(generidFun(2)) -} - diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/correctMember.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/correctMember.kt index eec10acfb95..302b2cfd873 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/correctMember.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/correctMember.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !USE_EXPERIMENTAL: kotlin.RequiresOptIn // !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/doubleColonExpressionToClassWithParameters.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/doubleColonExpressionToClassWithParameters.fir.kt deleted file mode 100644 index 07677c31ef0..00000000000 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/doubleColonExpressionToClassWithParameters.fir.kt +++ /dev/null @@ -1,38 +0,0 @@ -// !USE_EXPERIMENTAL: kotlin.RequiresOptIn -// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER -UNUSED_EXPRESSION - -@file:OptIn(ExperimentalTypeInference::class) - -package a.b - -import kotlin.experimental.ExperimentalTypeInference - -class BatchInfo1(val batchSize: Int) -class BatchInfo2(val data: T) - -object Obj - -fun test1() { - val a: Sequence = sequence { - val x = BatchInfo1::class - val y = a.b.BatchInfo1::class - val z = Obj::class - - val x1 = BatchInfo1::batchSize - val y1 = a.b.BatchInfo1::class - } -} - -interface Scope { - fun yield(t: T) {} -} - -fun generate(@BuilderInference g: Scope.() -> Unit): S = TODO() - -val test2 = generate { - { yield("foo") }::class -} - -val test3 = generate { - ({ yield("foo") })::class -} diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/doubleColonExpressionToClassWithParameters.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/doubleColonExpressionToClassWithParameters.kt index 0521de6290a..3e529dcd228 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/doubleColonExpressionToClassWithParameters.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/doubleColonExpressionToClassWithParameters.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !USE_EXPERIMENTAL: kotlin.RequiresOptIn // !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER -UNUSED_EXPRESSION diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/extensionSuspend.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/extensionSuspend.fir.kt deleted file mode 100644 index 026b4bdceff..00000000000 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/extensionSuspend.fir.kt +++ /dev/null @@ -1,43 +0,0 @@ -// !USE_EXPERIMENTAL: kotlin.RequiresOptIn -// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE - -@file:OptIn(ExperimentalTypeInference::class) - -import kotlin.experimental.ExperimentalTypeInference - -class GenericController { - suspend fun yield(t: T) {} -} - -@BuilderInference -suspend fun GenericController.yieldAll(s: Collection) {} - -fun generate(@BuilderInference g: suspend GenericController.() -> Unit): S = TODO() - -val test1 = generate { - yield(4) - yieldAll(setOf(4, 5)) -} - -val test2 = generate { - yieldAll(setOf(B)) -} - -val test3 = generate { - yieldAll(setOf(B, C)) -} - -val test4 = generate { - yieldAll(setOf(B)) - - yield(C) -} - - - -// Utils -fun setOf(vararg x: X): Set = TODO() - -interface A -object B : A -object C : A \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/extensionSuspend.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/extensionSuspend.kt index e34a1dc5931..3a4884bddbf 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/extensionSuspend.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/extensionSuspend.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !USE_EXPERIMENTAL: kotlin.RequiresOptIn // !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/extensionWithNonValuableConstraints.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/extensionWithNonValuableConstraints.fir.kt index 98f15521687..d8915915fa1 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/extensionWithNonValuableConstraints.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/extensionWithNonValuableConstraints.fir.kt @@ -25,7 +25,7 @@ fun Controller.genericExtension() {} fun Controller.safeExtension() {} val test1 = generate { - yield("foo") + yield("foo") baseExtension() } @@ -34,7 +34,7 @@ val test2 = generate { } val test3 = generate { - yield(42) + yield(42) outNullableAnyExtension() } @@ -43,20 +43,20 @@ val test4 = generate { } val test5 = generate { - yield(42) + yield(42) outAnyExtension() } val test6 = generate { - yield("bar") - invNullableAnyExtension() + yield("bar") + invNullableAnyExtension() } val test7 = generate { - yield("baz") - genericExtension() + yield("baz") + genericExtension() } val test8 = generate { - safeExtension() + safeExtension() } \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/extensionsWithNonValuableConstraintsGenericBase.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/extensionsWithNonValuableConstraintsGenericBase.fir.kt index 4e995beb5c8..d81a3c85025 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/extensionsWithNonValuableConstraintsGenericBase.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/extensionsWithNonValuableConstraintsGenericBase.fir.kt @@ -25,7 +25,7 @@ fun Base.stringBase() {} val test1 = generate { starBase() - yield("foo") + yield("foo") } val test2 = generate { @@ -33,17 +33,17 @@ val test2 = generate { } val test3 = generate { - yield("bar") - stringBase() + yield("bar") + stringBase() } val test4 = generateSpecific { - yield(42) + yield(42) starBase() } val test5 = generateSpecific { - yield(42) + yield(42) stringBase() } diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/incorrectCalls.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/incorrectCalls.fir.kt index adf0fe1bd86..cf1b8c54790 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/incorrectCalls.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/incorrectCalls.fir.kt @@ -17,20 +17,20 @@ class GenericController { fun generate(@BuilderInference g: suspend GenericController.() -> Unit): List = TODO() val test1 = generate { - yield(3) + yield(3) } val test2 = generate { - yield(3) - notYield(3) + yield(3) + notYield(3) } val test3 = generate { - yield(3) - yieldBarReturnType(3) + yield(3) + yieldBarReturnType(3) } val test4 = generate { - yield(3) + yield(3) barReturnType() } \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/kt35684.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/kt35684.fir.kt index 08dbf3a4b27..f55f52aba1a 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/kt35684.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/kt35684.fir.kt @@ -6,21 +6,21 @@ import kotlin.experimental.ExperimentalTypeInference fun test_1() { - sequence { - yield(")!>materialize()) - yield(materialize()) + ")!>sequence { + yield(")!>materialize()) + yield(materialize()) } } fun test_2() { sequence { - yield(materialize()) + yield(materialize()) } } fun test_3() { sequence { - yield(materialize()) + yield(materialize()) materialize() } } diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/kt38667.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/kt38667.fir.kt deleted file mode 100644 index e6d86e171ff..00000000000 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/kt38667.fir.kt +++ /dev/null @@ -1,34 +0,0 @@ -// !USE_EXPERIMENTAL: kotlin.RequiresOptIn -// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE -UNUSED_EXPRESSION - -import kotlin.experimental.ExperimentalTypeInference - -abstract class AnimationVector -class AnimationVector1D : AnimationVector() -interface PropKey -class IntPropKey : PropKey -abstract class AnimationBuilder -abstract class DurationBasedAnimationBuilder : AnimationBuilder() -class TweenBuilder : DurationBasedAnimationBuilder() -class TransitionSpec { - fun tween(init: TweenBuilder.() -> Unit): DurationBasedAnimationBuilder = TweenBuilder().apply(init) - infix fun PropKey.using(builder: AnimationBuilder) {} -} -class TransitionDefinition { - fun transition(fromState: T? = null, toState: T? = null, init: TransitionSpec.() -> Unit) {} -} -@OptIn(ExperimentalTypeInference::class) -fun transitionDefinition(@BuilderInference init: TransitionDefinition.() -> Unit) = TransitionDefinition().apply(init) - -fun main() { - val intProp = IntPropKey() - val defn = transitionDefinition { - transition(1, 2) { - intProp using tween { - - } - } - } - - ")!>defn -} diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/kt38667.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/kt38667.kt index be4ad0ff937..89e4329ac7b 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/kt38667.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/kt38667.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !USE_EXPERIMENTAL: kotlin.RequiresOptIn // !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE -UNUSED_EXPRESSION diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/qualifiedResolvedExpressionInsideBuilderInference.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/qualifiedResolvedExpressionInsideBuilderInference.fir.kt deleted file mode 100644 index 628e88980c9..00000000000 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/qualifiedResolvedExpressionInsideBuilderInference.fir.kt +++ /dev/null @@ -1,20 +0,0 @@ -// !USE_EXPERIMENTAL: kotlin.RequiresOptIn -// !DIAGNOSTICS: -UNUSED_PARAMETER - -import kotlin.experimental.ExperimentalTypeInference - -fun test() { - flow { - emit(42) - kotlin.coroutines.coroutineContext - } -} - -@OptIn(ExperimentalTypeInference::class) -fun flow(@BuilderInference block: suspend FlowCollector.() -> Unit): Flow = TODO() - -interface Flow - -interface FlowCollector { - suspend fun emit(value: T) -} diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/qualifiedResolvedExpressionInsideBuilderInference.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/qualifiedResolvedExpressionInsideBuilderInference.kt index 171813ac974..2697ff5a895 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/qualifiedResolvedExpressionInsideBuilderInference.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/qualifiedResolvedExpressionInsideBuilderInference.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !USE_EXPERIMENTAL: kotlin.RequiresOptIn // !DIAGNOSTICS: -UNUSED_PARAMETER diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/recursiveGenerators.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/recursiveGenerators.fir.kt deleted file mode 100644 index 8876e91e10e..00000000000 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/recursiveGenerators.fir.kt +++ /dev/null @@ -1,22 +0,0 @@ -// !USE_EXPERIMENTAL: kotlin.RequiresOptIn -// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE - -@file:OptIn(ExperimentalTypeInference::class) - -import kotlin.experimental.ExperimentalTypeInference - -class GenericController { - suspend fun yield(t: T) {} -} - -fun generate(@BuilderInference g: suspend GenericController.() -> Unit): List = TODO() - -val test1 = generate { - yield(generate { - yield(generate { - yield(generate { - yield(3) - }) - }) - }) -} diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/recursiveGenerators.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/recursiveGenerators.kt index 2e0b05e1a85..78ee07862ca 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/recursiveGenerators.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/recursiveGenerators.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !USE_EXPERIMENTAL: kotlin.RequiresOptIn // !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/recursiveGenerators2.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/recursiveGenerators2.fir.kt index 163ed6bdcd1..c2f11e09f17 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/recursiveGenerators2.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/recursiveGenerators2.fir.kt @@ -18,7 +18,7 @@ suspend fun GenericController>.yieldGenerate(g: suspend GenericContr val test1 = generate { // TODO: KT-15185 - yieldGenerate { - yield(4) + yieldGenerate { + yield(4) } } \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/resolveUsualCallWithBuilderInference.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/resolveUsualCallWithBuilderInference.fir.kt index 1168a2133ce..a03169e2e17 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/resolveUsualCallWithBuilderInference.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/resolveUsualCallWithBuilderInference.fir.kt @@ -21,7 +21,7 @@ fun Builder.extensionAdd(s: S) {} fun Builder.safeExtensionAdd(s: S) {} val member = build { - add(42) + add(42) } val memberWithoutAnn = wrongBuild { @@ -29,9 +29,9 @@ val memberWithoutAnn = wrongBuild { } val extension = build { - extensionAdd("foo") + extensionAdd("foo") } val safeExtension = build { - safeExtensionAdd("foo") + safeExtensionAdd("foo") } diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/simpleGenerator.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/simpleGenerator.fir.kt deleted file mode 100644 index 9c77bd81531..00000000000 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/simpleGenerator.fir.kt +++ /dev/null @@ -1,34 +0,0 @@ -// !USE_EXPERIMENTAL: kotlin.RequiresOptIn -// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE - -@file:OptIn(ExperimentalTypeInference::class) - -import kotlin.experimental.ExperimentalTypeInference - -class GenericController { - suspend fun yield(t: T) {} - suspend fun yieldSet(t: Set) {} - suspend fun yieldVararg(vararg t: T) {} -} - -fun generate(@BuilderInference g: suspend GenericController.() -> Unit): S = TODO() - -val test1 = generate { - yield(4) -} - -val test2 = generate { - yieldSet(setOf(1, 2, 3)) -} - -val test3 = generate { - yieldVararg(1, 2, 3) -} - -val test4 = generate { - yieldVararg(1, 2, "") -} - - -// Util function -fun setOf(vararg x: X): Set = TODO() \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/simpleGenerator.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/simpleGenerator.kt index a120873a563..86b70955a85 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/simpleGenerator.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/simpleGenerator.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !USE_EXPERIMENTAL: kotlin.RequiresOptIn // !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/suspendCallsWithErrors.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/suspendCallsWithErrors.fir.kt index 5e54cf716e4..32d9df49a67 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/suspendCallsWithErrors.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/suspendCallsWithErrors.fir.kt @@ -16,9 +16,9 @@ fun generate(@BuilderInference g: suspend Controller.() -> Unit): S = TOD class A val test1 = generate { - yield(A) + yield(A) } val test2: Int = generate { - yield(A()) + yield(A()) } \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/typeFromReceiver.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/typeFromReceiver.fir.kt deleted file mode 100644 index dbbef596d4c..00000000000 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/typeFromReceiver.fir.kt +++ /dev/null @@ -1,17 +0,0 @@ -// !USE_EXPERIMENTAL: kotlin.RequiresOptIn -// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE - -@file:OptIn(ExperimentalTypeInference::class) - -import kotlin.experimental.ExperimentalTypeInference - -class GenericController - -fun generate(@BuilderInference g: suspend GenericController.() -> Unit): List = TODO() - -@BuilderInference -suspend fun GenericController>.test() {} - -val test1 = generate { - test() -} \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/typeFromReceiver.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/typeFromReceiver.kt index 6f6efda3035..7fb1bc41083 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/typeFromReceiver.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/typeFromReceiver.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !USE_EXPERIMENTAL: kotlin.RequiresOptIn // !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/useInferenceInformationFromExtension.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/useInferenceInformationFromExtension.fir.kt index 233bebd2e15..db4efb8fc5d 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/useInferenceInformationFromExtension.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/useInferenceInformationFromExtension.fir.kt @@ -21,13 +21,13 @@ suspend fun GenericController.safeExtensionYield(s: S) {} fun generate(@BuilderInference g: suspend GenericController.() -> Unit): List = TODO() val normal = generate { - yield(42) + yield(42) } val extension = generate { - extensionYield("foo") + extensionYield("foo") } val safeExtension = generate { - safeExtensionYield("foo") + safeExtensionYield("foo") } \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/restrictSuspension/outerYield_1_3.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/restrictSuspension/outerYield_1_3.fir.kt index 5135c5e569a..31050be60fe 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/restrictSuspension/outerYield_1_3.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/restrictSuspension/outerYield_1_3.fir.kt @@ -84,10 +84,10 @@ fun test() { with(this) { yield("") - this@with.yield("") + this@with.yield("") yield2("") - this@with.yield2("") + this@with.yield2("") } } } diff --git a/compiler/testData/ir/irText/types/castsInsideCoroutineInference.fir.txt b/compiler/testData/ir/irText/types/castsInsideCoroutineInference.fir.txt index b2263411a89..55c5dbc6cc2 100644 --- a/compiler/testData/ir/irText/types/castsInsideCoroutineInference.fir.txt +++ b/compiler/testData/ir/irText/types/castsInsideCoroutineInference.fir.txt @@ -14,8 +14,8 @@ FILE fqName: fileName:/castsInsideCoroutineInference.kt FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> ($receiver:.FlowCollector.scopedFlow>) returnType:kotlin.Unit [suspend] $receiver: VALUE_PARAMETER name: type:.FlowCollector.scopedFlow> BLOCK_BODY - VAR name:collector type:.FlowCollector.scopedFlow> [val] - GET_VAR ': .FlowCollector.scopedFlow> declared in .scopedFlow.' type=.FlowCollector.scopedFlow> origin=null + VAR name:collector type:.FlowCollector [val] + GET_VAR ': .FlowCollector.scopedFlow> declared in .scopedFlow.' type=.FlowCollector origin=null CALL 'public final fun flowScope (block: kotlin.coroutines.SuspendFunction1<.CoroutineScope, R of .flowScope>): R of .flowScope [suspend] declared in ' type=kotlin.Unit origin=null : kotlin.Unit block: FUN_EXPR type=kotlin.coroutines.SuspendFunction1<.CoroutineScope, kotlin.Unit> origin=LAMBDA @@ -25,7 +25,7 @@ FILE fqName: fileName:/castsInsideCoroutineInference.kt CALL 'public abstract fun invoke (p1: P1 of kotlin.coroutines.SuspendFunction2, p2: P2 of kotlin.coroutines.SuspendFunction2): R of kotlin.coroutines.SuspendFunction2 [suspend,operator] declared in kotlin.coroutines.SuspendFunction2' type=kotlin.Unit origin=null $this: GET_VAR 'block: kotlin.coroutines.SuspendFunction2<.CoroutineScope, .FlowCollector.scopedFlow>, kotlin.Unit> declared in .scopedFlow' type=kotlin.coroutines.SuspendFunction2<.CoroutineScope, .FlowCollector.scopedFlow>, kotlin.Unit> origin=null p1: GET_VAR ': .CoroutineScope declared in .scopedFlow..' type=.CoroutineScope origin=null - p2: GET_VAR 'val collector: .FlowCollector.scopedFlow> [val] declared in .scopedFlow.' type=.FlowCollector.scopedFlow> origin=null + p2: GET_VAR 'val collector: .FlowCollector [val] declared in .scopedFlow.' type=.FlowCollector origin=null FUN name:onCompletion visibility:public modality:FINAL ($receiver:.Flow.onCompletion>, action:kotlin.coroutines.SuspendFunction2<.FlowCollector.onCompletion>, kotlin.Throwable?, kotlin.Unit>) returnType:.Flow.onCompletion> TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.Any?] $receiver: VALUE_PARAMETER name: type:.Flow.onCompletion> @@ -38,13 +38,13 @@ FILE fqName: fileName:/castsInsideCoroutineInference.kt FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> ($receiver:.FlowCollector.onCompletion>) returnType:kotlin.Unit [suspend] $receiver: VALUE_PARAMETER name: type:.FlowCollector.onCompletion> BLOCK_BODY - VAR name:safeCollector type:.SafeCollector.onCompletion> [val] - CONSTRUCTOR_CALL 'public constructor (collector: .FlowCollector.SafeCollector>) [primary] declared in .SafeCollector' type=.SafeCollector.onCompletion> origin=null - : T of .onCompletion - collector: GET_VAR ': .FlowCollector.onCompletion> declared in .onCompletion.' type=.FlowCollector.onCompletion> origin=null + VAR name:safeCollector type:.SafeCollector [val] + CONSTRUCTOR_CALL 'public constructor (collector: .FlowCollector.SafeCollector>) [primary] declared in .SafeCollector' type=.SafeCollector origin=null + : IrErrorType + collector: GET_VAR ': .FlowCollector.onCompletion> declared in .onCompletion.' type=.FlowCollector origin=null CALL 'public final fun invokeSafely (action: kotlin.coroutines.SuspendFunction2<.FlowCollector.invokeSafely>, kotlin.Throwable?, kotlin.Unit>): kotlin.Unit [suspend] declared in ' type=kotlin.Unit origin=null : T of .onCompletion - $receiver: GET_VAR 'val safeCollector: .SafeCollector.onCompletion> [val] declared in .onCompletion.' type=.SafeCollector.onCompletion> origin=null + $receiver: GET_VAR 'val safeCollector: .SafeCollector [val] declared in .onCompletion.' type=.SafeCollector origin=null action: GET_VAR 'action: kotlin.coroutines.SuspendFunction2<.FlowCollector.onCompletion>, kotlin.Throwable?, kotlin.Unit> declared in .onCompletion' type=kotlin.coroutines.SuspendFunction2<.FlowCollector.onCompletion>, kotlin.Throwable?, kotlin.Unit> origin=null FUN name:invokeSafely visibility:public modality:FINAL ($receiver:.FlowCollector.invokeSafely>, action:kotlin.coroutines.SuspendFunction2<.FlowCollector.invokeSafely>, kotlin.Throwable?, kotlin.Unit>) returnType:kotlin.Unit [suspend] TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.Any?] @@ -90,8 +90,8 @@ FILE fqName: fileName:/castsInsideCoroutineInference.kt BLOCK_BODY VAR name:channel type:.ChannelCoroutine [val] TYPE_OP type=.ChannelCoroutine origin=CAST typeOperand=.ChannelCoroutine - CALL 'public abstract fun (): .SendChannel.ProducerScope> declared in .ProducerScope' type=.SendChannel origin=GET_PROPERTY - $this: GET_VAR ': .ProducerScope declared in .asFairChannel.' type=.ProducerScope origin=null + CALL 'public abstract fun (): .SendChannel.ProducerScope> declared in .ProducerScope' type=.SendChannel origin=GET_PROPERTY + $this: GET_VAR ': .ProducerScope declared in .asFairChannel.' type=.ProducerScope origin=null CALL 'public abstract fun collect (collector: .FlowCollector.Flow>): kotlin.Unit [suspend] declared in .Flow' type=kotlin.Unit origin=null $this: GET_VAR 'flow: .Flow<*> declared in .asFairChannel' type=.Flow<*> origin=null collector: TYPE_OP type=.FlowCollector origin=SAM_CONVERSION typeOperand=.FlowCollector @@ -136,8 +136,8 @@ FILE fqName: fileName:/castsInsideCoroutineInference.kt BLOCK_BODY RETURN type=kotlin.Nothing from='local final fun (value: kotlin.Any?): kotlin.Unit declared in .asChannel.' CALL 'public abstract fun send (e: E of .SendChannel): kotlin.Unit [suspend] declared in .SendChannel' type=kotlin.Unit origin=null - $this: CALL 'public abstract fun (): .SendChannel.ProducerScope> declared in .ProducerScope' type=.SendChannel origin=GET_PROPERTY - $this: GET_VAR ': .ProducerScope declared in .asChannel.' type=.ProducerScope origin=null + $this: CALL 'public abstract fun (): .SendChannel.ProducerScope> declared in .ProducerScope' type=.SendChannel origin=GET_PROPERTY + $this: GET_VAR ': .ProducerScope declared in .asChannel.' type=.ProducerScope origin=null e: BLOCK type=kotlin.Any origin=ELVIS VAR IR_TEMPORARY_VARIABLE name:tmp_1 type:kotlin.Any? [val] GET_VAR 'value: kotlin.Any? declared in .asChannel..' type=kotlin.Any? origin=null