diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConeInferenceContext.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConeInferenceContext.kt index 3c1537b93b3..05caf72aaea 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConeInferenceContext.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConeInferenceContext.kt @@ -256,7 +256,7 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, } override fun typeSubstitutorByTypeConstructor(map: Map): TypeSubstitutorMarker { - if (map.isEmpty()) return ConeSubstitutor.Empty + if (map.isEmpty()) return createEmptySubstitutor() return object : AbstractConeSubstitutor(), TypeSubstitutorMarker { override fun substituteType(type: ConeKotlinType): ConeKotlinType? { @@ -266,6 +266,10 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, } } + override fun createEmptySubstitutor(): TypeSubstitutorMarker { + return ConeSubstitutor.Empty + } + override fun TypeSubstitutorMarker.safeSubstitute(type: KotlinTypeMarker): KotlinTypeMarker { if (this === NoSubstitutor) return type require(this is ConeSubstitutor) 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 aab3af509e6..37409a83592 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 @@ -27,6 +27,7 @@ import org.jetbrains.kotlin.fir.types.impl.FirResolvedTypeRefImpl import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.calls.components.InferenceSession import org.jetbrains.kotlin.resolve.calls.inference.buildAbstractResultingSubstitutor +import org.jetbrains.kotlin.resolve.calls.inference.components.EmptySubstitutor import org.jetbrains.kotlin.resolve.calls.inference.components.KotlinConstraintSystemCompleter import org.jetbrains.kotlin.resolve.calls.inference.model.SimpleConstraintSystemConstraintPosition import org.jetbrains.kotlin.types.model.StubTypeMarker diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ClassicTypeSystemContextForCS.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ClassicTypeSystemContextForCS.kt index 0defce5d5af..5049cd87d33 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ClassicTypeSystemContextForCS.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ClassicTypeSystemContextForCS.kt @@ -7,6 +7,7 @@ package org.jetbrains.kotlin.resolve.calls.components import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.resolve.calls.inference.components.ConstraintInjector +import org.jetbrains.kotlin.resolve.calls.inference.components.EmptySubstitutor import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutor import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutorByConstructorMap import org.jetbrains.kotlin.resolve.calls.inference.model.NewConstraintSystemImpl @@ -60,9 +61,14 @@ class ClassicTypeSystemContextForCS(override val builtIns: KotlinBuiltIns) : Typ } override fun typeSubstitutorByTypeConstructor(map: Map): TypeSubstitutorMarker { + if (map.isEmpty()) return createEmptySubstitutor() return NewTypeSubstitutorByConstructorMap(map.cast()) } + override fun createEmptySubstitutor(): TypeSubstitutorMarker { + return EmptySubstitutor + } + override fun TypeSubstitutorMarker.safeSubstitute(type: KotlinTypeMarker): KotlinTypeMarker { require(type is UnwrappedType, type::errorMessage) return when (this) { diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/SimpleArgumentsChecks.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/SimpleArgumentsChecks.kt index fb92148f478..4ebb45d9385 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/SimpleArgumentsChecks.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/SimpleArgumentsChecks.kt @@ -51,8 +51,8 @@ private fun checkExpressionArgument( diagnosticsHolder: KotlinDiagnosticsHolder, isReceiver: Boolean ): ResolvedAtom { - val resolvedKtExpression = ResolvedExpressionAtom(expressionArgument) - if (expectedType == null) return resolvedKtExpression + val resolvedExpression = ResolvedExpressionAtom(expressionArgument) + if (expectedType == null) return resolvedExpression // todo run this approximation only once for call val argumentType = captureFromTypeParameterUpperBoundIfNeeded(expressionArgument.receiver.stableType, expectedType) @@ -77,7 +77,6 @@ private fun checkExpressionArgument( return null } - val expectedNullableType = expectedType.makeNullableAsSpecified(true) val position = if (isReceiver) ReceiverConstraintPosition(expressionArgument) else ArgumentConstraintPosition(expressionArgument) // Used only for arguments with @NotNull annotation @@ -86,12 +85,13 @@ private fun checkExpressionArgument( } if (expressionArgument.isSafeCall) { + val expectedNullableType = expectedType.makeNullableAsSpecified(true) if (!csBuilder.addSubtypeConstraintIfCompatible(argumentType, expectedNullableType, position)) { diagnosticsHolder.addDiagnosticIfNotNull( unstableSmartCastOrSubtypeError(expressionArgument.receiver.unstableType, expectedNullableType, position) ) } - return resolvedKtExpression + return resolvedExpression } if (!csBuilder.addSubtypeConstraintIfCompatible(argumentType, expectedType, position)) { @@ -103,10 +103,12 @@ private fun checkExpressionArgument( position ) ) - return resolvedKtExpression + return resolvedExpression } val unstableType = expressionArgument.receiver.unstableType + val expectedNullableType = expectedType.makeNullableAsSpecified(true) + if (unstableType != null && csBuilder.addSubtypeConstraintIfCompatible(unstableType, expectedType, position)) { diagnosticsHolder.addDiagnostic(UnstableSmartCast(expressionArgument, unstableType)) } else if (csBuilder.addSubtypeConstraintIfCompatible(argumentType, expectedNullableType, position)) { @@ -116,7 +118,7 @@ private fun checkExpressionArgument( } } - return resolvedKtExpression + return resolvedExpression } /** diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/InferenceUtils.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/InferenceUtils.kt index 0bbdd866bb6..68f4f4bd653 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/InferenceUtils.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/InferenceUtils.kt @@ -21,9 +21,10 @@ import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstituto import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns import org.jetbrains.kotlin.types.* -import org.jetbrains.kotlin.types.checker.ClassicTypeSystemContext -import org.jetbrains.kotlin.types.model.* -import java.util.* +import org.jetbrains.kotlin.types.model.StubTypeMarker +import org.jetbrains.kotlin.types.model.TypeConstructorMarker +import org.jetbrains.kotlin.types.model.TypeSubstitutorMarker +import org.jetbrains.kotlin.types.model.TypeSystemInferenceExtensionContext fun ConstraintStorage.buildCurrentSubstitutor( context: TypeSystemInferenceExtensionContext, @@ -34,6 +35,8 @@ fun ConstraintStorage.buildCurrentSubstitutor( fun ConstraintStorage.buildAbstractResultingSubstitutor(context: TypeSystemInferenceExtensionContext): TypeSubstitutorMarker = with(context) { + if (allTypeVariables.isEmpty()) return createEmptySubstitutor() + val currentSubstitutorMap = fixedTypeVariables.entries.associate { it.key to it.value } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/NewTypeSubstitutor.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/NewTypeSubstitutor.kt index 6773eddf166..c30bf22f83b 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/NewTypeSubstitutor.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/NewTypeSubstitutor.kt @@ -159,6 +159,10 @@ interface NewTypeSubstitutor: TypeSubstitutorMarker { } } +object EmptySubstitutor : NewTypeSubstitutor { + override fun substituteNotNullTypeWithConstructor(constructor: TypeConstructor): UnwrappedType? = null +} + class NewTypeSubstitutorByConstructorMap(val map: Map) : NewTypeSubstitutor { override fun substituteNotNullTypeWithConstructor(constructor: TypeConstructor): UnwrappedType? = map[constructor] } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/VariableFixationFinder.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/VariableFixationFinder.kt index 5b7c27acff0..f6019bceb8e 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/VariableFixationFinder.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/VariableFixationFinder.kt @@ -77,6 +77,8 @@ class VariableFixationFinder( completionMode: ConstraintSystemCompletionMode, topLevelType: KotlinTypeMarker ): VariableForFixation? { + if (allTypeVariables.isEmpty()) return null + val dependencyProvider = TypeVariableDependencyInformationProvider( notFixedTypeVariables, postponedArguments, topLevelType.takeIf { completionMode == PARTIAL }, this ) diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/NewConstraintSystemImpl.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/NewConstraintSystemImpl.kt index 0c7ee5eb519..e5702f2d271 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/NewConstraintSystemImpl.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/NewConstraintSystemImpl.kt @@ -179,6 +179,7 @@ class NewConstraintSystemImpl( // ResultTypeResolver.Context, ConstraintSystemBuilder override fun isProperType(type: KotlinTypeMarker): Boolean { checkState(State.BUILDING, State.COMPLETION, State.TRANSACTION) + if (storage.allTypeVariables.isEmpty()) return true return !type.contains { val capturedType = it.asSimpleType()?.asCapturedType() // TODO: change NewCapturedType to markered one for FE-IR 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 16e267cd5a4..f3270484151 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/checker/ClassicTypeSystemContext.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/checker/ClassicTypeSystemContext.kt @@ -456,6 +456,10 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSy errorSupportedOnlyInTypeInference() } + override fun createEmptySubstitutor(): TypeSubstitutorMarker { + errorSupportedOnlyInTypeInference() + } + override fun TypeSubstitutorMarker.safeSubstitute(type: KotlinTypeMarker): KotlinTypeMarker { require(type is UnwrappedType, type::errorMessage) require(this is TypeSubstitutor, this::errorMessage) diff --git a/core/type-system/src/org/jetbrains/kotlin/types/model/TypeSystemContext.kt b/core/type-system/src/org/jetbrains/kotlin/types/model/TypeSystemContext.kt index 786f771a7b5..00700c46038 100644 --- a/core/type-system/src/org/jetbrains/kotlin/types/model/TypeSystemContext.kt +++ b/core/type-system/src/org/jetbrains/kotlin/types/model/TypeSystemContext.kt @@ -146,6 +146,7 @@ interface TypeSystemInferenceExtensionContext : TypeSystemContext, TypeSystemBui fun DefinitelyNotNullTypeMarker.original(): SimpleTypeMarker fun typeSubstitutorByTypeConstructor(map: Map): TypeSubstitutorMarker + fun createEmptySubstitutor(): TypeSubstitutorMarker fun TypeSubstitutorMarker.safeSubstitute(type: KotlinTypeMarker): KotlinTypeMarker