diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/ConeConstraintSystemUtilContext.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/ConeConstraintSystemUtilContext.kt index e62abf21edb..5a12718b312 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/ConeConstraintSystemUtilContext.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/ConeConstraintSystemUtilContext.kt @@ -11,6 +11,7 @@ import org.jetbrains.kotlin.fir.resolve.inference.model.ConeFixVariableConstrain import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.fir.types.FirImplicitTypeRef import org.jetbrains.kotlin.fir.types.coneType +import org.jetbrains.kotlin.fir.types.coneTypeSafe import org.jetbrains.kotlin.resolve.calls.inference.components.ConstraintSystemUtilContext import org.jetbrains.kotlin.resolve.calls.inference.components.PostponedArgumentInputTypesResolver import org.jetbrains.kotlin.resolve.calls.inference.model.ArgumentConstraintPosition @@ -56,7 +57,8 @@ object ConeConstraintSystemUtilContext : ConstraintSystemUtilContext { return ConeFixVariableConstraintPosition(variable) as FixVariableConstraintPosition } - override fun extractParameterTypesFromDeclaration(declaration: PostponedAtomWithRevisableExpectedType): List? { + @OptIn(ExperimentalStdlibApi::class) + override fun extractLambdaParameterTypesFromDeclaration(declaration: PostponedAtomWithRevisableExpectedType): List? { require(declaration is PostponedResolvedAtom) return when (declaration) { is LambdaWithTypeVariableAsExpectedTypeAtom -> { @@ -66,7 +68,7 @@ object ConeConstraintSystemUtilContext : ConstraintSystemUtilContext { atom.collectDeclaredValueParameterTypes() else null } else { // function expression - all types are explicit, shouldn't return null - mutableListOf().apply { + buildList { atom.receiverTypeRef?.coneType?.let { add(it) } addAll(atom.collectDeclaredValueParameterTypes()) } @@ -77,11 +79,7 @@ object ConeConstraintSystemUtilContext : ConstraintSystemUtilContext { } private fun FirAnonymousFunction.collectDeclaredValueParameterTypes(): List = - valueParameters.map { - if (it.returnTypeRef !is FirImplicitTypeRef) - it.returnTypeRef.coneType - else null - } + valueParameters.map { it.returnTypeRef.coneTypeSafe() } override fun PostponedAtomWithRevisableExpectedType.isAnonymousFunction(): Boolean { require(this is PostponedResolvedAtom) @@ -102,7 +100,7 @@ object ConeConstraintSystemUtilContext : ConstraintSystemUtilContext { index: Int ): TypeVariableMarker { return ConeTypeVariableForPostponedAtom( - "${PostponedArgumentInputTypesResolver.TYPE_VARIABLE_NAME_PREFIX_FOR_LAMBDA_PARAMETER_TYPE}$index" + PostponedArgumentInputTypesResolver.TYPE_VARIABLE_NAME_PREFIX_FOR_LAMBDA_PARAMETER_TYPE + index ) } @@ -111,7 +109,7 @@ object ConeConstraintSystemUtilContext : ConstraintSystemUtilContext { index: Int ): TypeVariableMarker { return ConeTypeVariableForPostponedAtom( - "${PostponedArgumentInputTypesResolver.TYPE_VARIABLE_NAME_PREFIX_FOR_CR_PARAMETER_TYPE}$index" + PostponedArgumentInputTypesResolver.TYPE_VARIABLE_NAME_PREFIX_FOR_CR_PARAMETER_TYPE + index ) } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/ConstraintSystemCompleter.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/ConstraintSystemCompleter.kt index 02ded0f33d3..ea7d642e11e 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/ConstraintSystemCompleter.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/ConstraintSystemCompleter.kt @@ -158,10 +158,8 @@ class ConstraintSystemCompleter(private val components: BodyResolveComponents) { argument.revisedExpectedType?.takeIf { it.isFunctionOrKFunctionWithAnySuspendability() }?.cast() ?: return false when (argument) { - is ResolvedCallableReferenceAtom -> { + is ResolvedCallableReferenceAtom -> argument.reviseExpectedType(revisedExpectedType) - } - is LambdaWithTypeVariableAsExpectedTypeAtom -> argument.transformToResolvedLambda(c.getBuilder(), resolutionContext, revisedExpectedType, null /*TODO()*/) else -> throw IllegalStateException("Unsupported postponed argument type of $argument") @@ -188,7 +186,7 @@ class ConstraintSystemCompleter(private val components: BodyResolveComponents) { } // Avoiding smart cast from filterIsInstanceOrNull looks dirty - private fun findPostponedArgumentWithRevisableExpectedType(postponedArguments: List) = + private fun findPostponedArgumentWithRevisableExpectedType(postponedArguments: List): PostponedResolvedAtom? = postponedArguments.firstOrNull { argument -> argument is PostponedAtomWithRevisableExpectedType } private fun ConstraintSystemCompletionContext.fixVariablesOrReportNotEnoughInformation( @@ -263,9 +261,14 @@ class ConstraintSystemCompleter(private val components: BodyResolveComponents) { // TODO: non-top-level variables? fun PostponedAtomWithRevisableExpectedType.collectNotFixedVariables() { - revisedExpectedType?.getArguments()?.map { it.getType().typeConstructor() } - ?.filterIsInstance().orEmpty() - .mapNotNullTo(result) { it.takeIf { it in notFixedTypeVariables } } + revisedExpectedType?.lowerBoundIfFlexible()?.asArgumentList()?.let { typeArgumentList -> + for (typeArgument in typeArgumentList) { + val constructor = typeArgument.getType().typeConstructor() + if (constructor in notFixedTypeVariables) { + result.add(constructor) + } + } + } } fun FirStatement.collectAllTypeVariables() { 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 b7257206100..d5d683b683c 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 @@ -214,8 +214,7 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo override fun KotlinTypeMarker.isBuiltinFunctionalTypeOrSubtype(): Boolean { require(this is ConeKotlinType) return this.isTypeOrSubtypeOf { - it.lowerBoundIfFlexible().safeAs()?.isBuiltinFunctionalType(session) - ?: error("Unexpected lower bound for type: ${it.render()}") + (it.lowerBoundIfFlexible() as ConeKotlinType).isBuiltinFunctionalType(session) } } @@ -402,7 +401,8 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo this, { // FIXME supertypes of type constructor contain unsubstituted arguments - it.typeConstructor().supertypes().cast>() + @Suppress("UNCHECKED_CAST") + it.typeConstructor().supertypes() as Collection }, DFS.VisitedWithSet(), object : DFS.AbstractNodeHandler() { @@ -423,8 +423,7 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo override fun KotlinTypeMarker.isSuspendFunctionTypeOrSubtype(): Boolean { require(this is ConeKotlinType) return isTypeOrSubtypeOf { - it.lowerBoundIfFlexible().safeAs()?.isSuspendFunctionType(session) - ?: error("Unexpected lower bound for type: ${it.render()}") + (it.lowerBoundIfFlexible() as ConeKotlinType).isSuspendFunctionType(session) } } @@ -433,7 +432,7 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo return this.lowerBoundIfFlexible().safeAs()?.isExtensionFunctionType(session) == true } - @ExperimentalStdlibApi + @OptIn(ExperimentalStdlibApi::class) override fun KotlinTypeMarker.extractArgumentsForFunctionalTypeOrSubtype(): List { val builtInFunctionalType = getFunctionalTypeFromSupertypes().cast() return buildList { @@ -452,7 +451,7 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo return fullyExpandedType(session).let { val simpleType = it.lowerBoundIfFlexible() - if (simpleType.safeAs()?.isBuiltinFunctionalType(session) == true) + if ((simpleType as ConeKotlinType).isBuiltinFunctionalType(session)) this else { var functionalSupertype: KotlinTypeMarker? = null diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt index 17391df4083..179bebe402f 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt @@ -160,12 +160,6 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty ?: session.builtinTypes.anyType.type//StandardClassIds.Any(session.firSymbolProvider).constructType(emptyArray(), false) // TODO wtf } - override fun KotlinTypeMarker.getArguments(): List { - require(this is ConeKotlinType) - - return this.typeArguments.toList() - } - override fun KotlinTypeMarker.asTypeArgument(): TypeArgumentMarker { require(this is ConeKotlinType) diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSystemContext.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSystemContext.kt index 18eb7159ac4..37851add71b 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSystemContext.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSystemContext.kt @@ -94,12 +94,6 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon else -> error("Type $this has no arguments") } - override fun KotlinTypeMarker.getArguments(): List = - when (this) { - is IrSimpleType -> arguments - else -> error("Type $this has no arguments") - } - override fun KotlinTypeMarker.asTypeArgument() = this as IrTypeArgument override fun CapturedTypeMarker.lowerType(): KotlinTypeMarker? = error("Captured Type is not valid for IrTypes") diff --git a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/ConstraintSystemUtilContext.kt b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/ConstraintSystemUtilContext.kt index 973bf0ce2f8..539e4700e1b 100644 --- a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/ConstraintSystemUtilContext.kt +++ b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/ConstraintSystemUtilContext.kt @@ -27,7 +27,7 @@ interface ConstraintSystemUtilContext { // PostponedArgumentInputTypesResolver fun createArgumentConstraintPosition(argument: T): ArgumentConstraintPosition fun createFixVariableConstraintPosition(variable: TypeVariableMarker, atom: T): FixVariableConstraintPosition - fun extractParameterTypesFromDeclaration(declaration: PostponedAtomWithRevisableExpectedType): List? + fun extractLambdaParameterTypesFromDeclaration(declaration: PostponedAtomWithRevisableExpectedType): List? fun PostponedAtomWithRevisableExpectedType.isAnonymousFunction(): Boolean fun PostponedAtomWithRevisableExpectedType.isFunctionExpressionWithReceiver(): Boolean fun createTypeVariableForLambdaReturnType(): TypeVariableMarker diff --git a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/PostponedArgumentInputTypesResolver.kt b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/PostponedArgumentInputTypesResolver.kt index f4b2269d5c5..a25501a4d12 100644 --- a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/PostponedArgumentInputTypesResolver.kt +++ b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/PostponedArgumentInputTypesResolver.kt @@ -332,7 +332,7 @@ class PostponedArgumentInputTypesResolver( for (argument in postponedArguments) { if (argument !is LambdaWithTypeVariableAsExpectedTypeMarker) continue if (argument.parameterTypesFromDeclaration != null) continue - argument.updateParameterTypesFromDeclaration(extractParameterTypesFromDeclaration(argument)) + argument.updateParameterTypesFromDeclaration(extractLambdaParameterTypesFromDeclaration(argument)) } return postponedArguments.any { argument -> @@ -359,21 +359,33 @@ class PostponedArgumentInputTypesResolver( private fun Context.getAllDeeplyRelatedTypeVariables( type: KotlinTypeMarker, - variableDependencyProvider: TypeVariableDependencyInformationProvider - ): List { + variableDependencyProvider: TypeVariableDependencyInformationProvider, + ): Collection { + val collectedVariables = mutableSetOf() + getAllDeeplyRelatedTypeVariables(type, variableDependencyProvider, collectedVariables) + return collectedVariables + } + + private fun Context.getAllDeeplyRelatedTypeVariables( + type: KotlinTypeMarker, + variableDependencyProvider: TypeVariableDependencyInformationProvider, + typeVariableCollector: MutableSet + ) { val typeConstructor = type.typeConstructor() - return when { + when { typeConstructor is TypeVariableTypeConstructorMarker -> { val relatedVariables = variableDependencyProvider.getDeeplyDependentVariables(typeConstructor).orEmpty() - listOf(typeConstructor) + relatedVariables.filterIsInstance() + typeVariableCollector.add(typeConstructor) + typeVariableCollector.addAll(relatedVariables.filterIsInstance()) } type.argumentsCount() > 0 -> { - type.getArguments().flatMap { - if (it.isStarProjection()) emptyList() else getAllDeeplyRelatedTypeVariables(it.getType(), variableDependencyProvider) + for (typeArgument in type.lowerBoundIfFlexible().asArgumentList()) { + if (!typeArgument.isStarProjection()) { + getAllDeeplyRelatedTypeVariables(typeArgument.getType(), variableDependencyProvider, typeVariableCollector) + } } } - else -> emptyList() } } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/ClassicConstraintSystemUtilContext.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/ClassicConstraintSystemUtilContext.kt index 76f469e8ff9..6c2583e8041 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/ClassicConstraintSystemUtilContext.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/ClassicConstraintSystemUtilContext.kt @@ -63,7 +63,7 @@ class ClassicConstraintSystemUtilContext( return FixVariableConstraintPositionImpl(variable, atom) as FixVariableConstraintPosition } - override fun extractParameterTypesFromDeclaration(declaration: PostponedAtomWithRevisableExpectedType): List? { + override fun extractLambdaParameterTypesFromDeclaration(declaration: PostponedAtomWithRevisableExpectedType): List? { require(declaration is ResolvedAtom) return when (val atom = declaration.atom) { is FunctionExpression -> { diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/KotlinConstraintSystemCompleter.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/KotlinConstraintSystemCompleter.kt index e28b8e07035..8cd0ef22580 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/KotlinConstraintSystemCompleter.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/KotlinConstraintSystemCompleter.kt @@ -20,10 +20,8 @@ import org.jetbrains.kotlin.utils.addToStdlib.safeAs class KotlinConstraintSystemCompleter( private val resultTypeResolver: ResultTypeResolver, val variableFixationFinder: VariableFixationFinder, - private val ctx: ConstraintSystemUtilContext, + private val postponedArgumentInputTypesResolver: PostponedArgumentInputTypesResolver, ) { - private val postponedArgumentInputTypesResolver = PostponedArgumentInputTypesResolver(resultTypeResolver, variableFixationFinder, ctx) - fun runCompletion( c: ConstraintSystemCompletionContext, completionMode: ConstraintSystemCompletionMode, diff --git a/compiler/testData/codegen/box/closures/capturedVarsOptimization/capturedInInlineOnlyIndexedCAO.kt b/compiler/testData/codegen/box/closures/capturedVarsOptimization/capturedInInlineOnlyIndexedCAO.kt index 44e0531c7b7..11d2983d00f 100644 --- a/compiler/testData/codegen/box/closures/capturedVarsOptimization/capturedInInlineOnlyIndexedCAO.kt +++ b/compiler/testData/codegen/box/closures/capturedVarsOptimization/capturedInInlineOnlyIndexedCAO.kt @@ -1,3 +1,4 @@ +// IGNORE_BACKEND_FIR: JVM_IR // WITH_RUNTIME class Host(var value: String) { diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/extensionsWithNonValuableConstraints_1_2.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/extensionsWithNonValuableConstraints_1_2.fir.kt new file mode 100644 index 00000000000..ad18793da9d --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/extensionsWithNonValuableConstraints_1_2.fir.kt @@ -0,0 +1,17 @@ +// !LANGUAGE: -ExperimentalBuilderInference +// !DIAGNOSTICS: -UNUSED_PARAMETER + +interface Base + +interface Controller : Base { + suspend fun yield(t: T) {} +} + +fun generate(g: suspend Controller.() -> Unit): S = TODO() + +suspend fun Base.baseExtension() {} + +val test1 = generate { + yield("foo") + baseExtension() +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/extensionsWithNonValuableConstraints_1_2.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/extensionsWithNonValuableConstraints_1_2.kt index bcd4041ad8a..460262f44a4 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/extensionsWithNonValuableConstraints_1_2.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/extensionsWithNonValuableConstraints_1_2.kt @@ -1,4 +1,3 @@ -// FIR_IDENTICAL // !LANGUAGE: -ExperimentalBuilderInference // !DIAGNOSTICS: -UNUSED_PARAMETER @@ -13,6 +12,6 @@ fun generate(g: suspend Controller.() -> Unit): S = TODO() suspend fun Base.baseExtension() {} val test1 = generate { - yield("foo") + yield("foo") baseExtension() } diff --git a/core/compiler.common/src/org/jetbrains/kotlin/types/model/TypeSystemContext.kt b/core/compiler.common/src/org/jetbrains/kotlin/types/model/TypeSystemContext.kt index 1528abbfed3..37935eaf548 100644 --- a/core/compiler.common/src/org/jetbrains/kotlin/types/model/TypeSystemContext.kt +++ b/core/compiler.common/src/org/jetbrains/kotlin/types/model/TypeSystemContext.kt @@ -246,7 +246,6 @@ interface TypeSystemContext : TypeSystemOptimizationContext { fun KotlinTypeMarker.argumentsCount(): Int fun KotlinTypeMarker.getArgument(index: Int): TypeArgumentMarker - fun KotlinTypeMarker.getArguments(): List fun SimpleTypeMarker.getArgumentOrNull(index: Int): TypeArgumentMarker? { if (index in 0 until argumentsCount()) return getArgument(index) @@ -341,6 +340,18 @@ interface TypeSystemContext : TypeSystemOptimizationContext { } } + operator fun TypeArgumentListMarker.iterator() = object : Iterator { + private var argumentIndex: Int = 0 + + override fun hasNext(): Boolean = argumentIndex < size() + + override fun next(): TypeArgumentMarker { + val argument = get(argumentIndex) + argumentIndex += 1 + return argument + } + } + fun TypeConstructorMarker.isAnyConstructor(): Boolean fun TypeConstructorMarker.isNothingConstructor(): Boolean diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/checker/ClassicTypeSystemContext.kt b/core/descriptors/src/org/jetbrains/kotlin/types/checker/ClassicTypeSystemContext.kt index 0e1753d4d13..0a2eb70aa40 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/checker/ClassicTypeSystemContext.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/checker/ClassicTypeSystemContext.kt @@ -159,11 +159,6 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSy return this.arguments[index] } - override fun KotlinTypeMarker.getArguments(): List { - require(this is KotlinType, this::errorMessage) - return this.arguments - } - override fun TypeArgumentMarker.isStarProjection(): Boolean { require(this is TypeProjection, this::errorMessage) return this.isStarProjection