From 22c21ca4dfc63b6cb6df0c7bb4790db6614bd369 Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Tue, 18 Oct 2022 14:18:16 +0300 Subject: [PATCH] [FIR] Replace uninferred type variables and stub types during delegate inference --- .../fir/resolve/substitution/Substitutors.kt | 39 +++++++- .../FirDelegatedPropertyInferenceSession.kt | 8 +- .../FirDeclarationsResolveTransformer.kt | 2 - .../tests/delegation/kt44843.fir.kt | 4 +- .../tests/delegation/kt49477.fir.kt | 2 +- .../tests/delegation/kt49477Error.fir.kt | 2 +- .../stubTypeReceiverRestriction.fir.kt | 2 +- ...stubTypeReceiverRestrictionDisabled.fir.kt | 2 +- .../inference/delegates/kt50994.fir.kt | 3 +- .../inference/delegates/kt50994.fir.txt | 95 +++++++++++++++++++ .../inference/delegates/kt50994.kt | 1 + 11 files changed, 144 insertions(+), 16 deletions(-) create mode 100644 compiler/testData/diagnostics/testsWithStdLib/inference/delegates/kt50994.fir.txt diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/resolve/substitution/Substitutors.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/resolve/substitution/Substitutors.kt index 41adf8d4763..c9ceae3a883 100644 --- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/resolve/substitution/Substitutors.kt +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/resolve/substitution/Substitutors.kt @@ -6,6 +6,8 @@ package org.jetbrains.kotlin.fir.resolve.substitution import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic +import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind import org.jetbrains.kotlin.fir.resolve.fullyExpandedType import org.jetbrains.kotlin.fir.resolve.toFirRegularClassSymbol import org.jetbrains.kotlin.fir.resolve.withCombinedAttributesFrom @@ -19,6 +21,7 @@ import org.jetbrains.kotlin.types.model.TypeConstructorMarker import org.jetbrains.kotlin.types.model.TypeSubstitutorMarker import org.jetbrains.kotlin.types.model.TypeVariableMarker import org.jetbrains.kotlin.types.model.typeConstructor +import org.jetbrains.kotlin.utils.addToStdlib.runIf abstract class AbstractConeSubstitutor(protected val typeContext: ConeTypeContext) : ConeSubstitutor() { protected fun wrapProjection(old: ConeTypeProjection, newType: ConeKotlinType): ConeTypeProjection { @@ -285,12 +288,12 @@ fun createTypeSubstitutorByTypeConstructor( internal class ConeTypeSubstitutorByTypeConstructor( private val map: Map, - private val context: ConeTypeContext, + typeContext: ConeTypeContext, private val approximateIntegerLiterals: Boolean -) : AbstractConeSubstitutor(context), TypeSubstitutorMarker { +) : AbstractConeSubstitutor(typeContext), TypeSubstitutorMarker { override fun substituteType(type: ConeKotlinType): ConeKotlinType? { if (type !is ConeLookupTagBasedType && type !is ConeStubType) return null - val new = map[type.typeConstructor(context)] ?: return null + val new = map[type.typeConstructor(typeContext)] ?: return null val approximatedIntegerLiteralType = if (approximateIntegerLiterals) new.approximateIntegerLiteralType() else new return approximatedIntegerLiteralType.updateNullabilityIfNeeded(type)?.withCombinedAttributesFrom(type) } @@ -308,3 +311,33 @@ class NotFixedTypeToVariableSubstitutorForDelegateInference( } } +class ConeStubAndTypeVariableToErrorTypeSubstitutor( + typeContext: ConeTypeContext, + private val stubTypesToReplace: Collection +) : AbstractConeSubstitutor(typeContext) { + override fun substituteType(type: ConeKotlinType): ConeKotlinType? { + return when (type) { + is ConeTypeVariableType -> ConeErrorType( + ConeSimpleDiagnostic("Type for ${type.lookupTag.debugName} is not inferred", DiagnosticKind.InferenceError), + isUninferredParameter = true + ) + is ConeStubType -> runIf(type.constructor in stubTypesToReplace) { + ConeErrorType( + ConeSimpleDiagnostic( + "Type for stub of ${type.constructor.variable.typeConstructor.debugName} is not inferred", + DiagnosticKind.InferenceError + ), + isUninferredParameter = true + ) + } + else -> null + } + } +} + +fun ConeSubstitutor.replaceStubsAndTypeVariablesToErrors( + typeContext: ConeTypeContext, + stubTypesToReplace: Collection +): ConeSubstitutor { + return ChainedSubstitutor(this, ConeStubAndTypeVariableToErrorTypeSubstitutor(typeContext, stubTypesToReplace)) +} 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 9b610591c79..1bd438e3324 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 @@ -10,9 +10,7 @@ import org.jetbrains.kotlin.fir.expressions.FirResolvable import org.jetbrains.kotlin.fir.expressions.FirStatement import org.jetbrains.kotlin.fir.resolve.calls.* import org.jetbrains.kotlin.fir.resolve.inference.model.ConeFixVariableConstraintPosition -import org.jetbrains.kotlin.fir.resolve.substitution.ChainedSubstitutor -import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor -import org.jetbrains.kotlin.fir.resolve.substitution.NotFixedTypeToVariableSubstitutorForDelegateInference +import org.jetbrains.kotlin.fir.resolve.substitution.* import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder import org.jetbrains.kotlin.resolve.calls.inference.NewConstraintSystem @@ -228,9 +226,11 @@ class FirDelegatedPropertyInferenceSession( fun createFinalSubstitutor(): ConeSubstitutor { val stubTypeSubstitutor = createNonFixedTypeToVariableSubstitutor() + val typeContext = components.session.typeContext val resultSubstitutor = resultingConstraintSystem.asReadOnlyStorage() - .buildAbstractResultingSubstitutor(components.session.typeContext) as ConeSubstitutor + .buildAbstractResultingSubstitutor(typeContext) as ConeSubstitutor return ChainedSubstitutor(stubTypeSubstitutor, resultSubstitutor) + .replaceStubsAndTypeVariablesToErrors(typeContext, stubTypesByTypeVariable.values.map { it.constructor }) } val stubTypesByTypeVariable: MutableMap = mutableMapOf() diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt index 7e15eb3a41a..8e562739ad2 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt @@ -265,7 +265,6 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor } private fun transformPropertyAccessorsWithDelegate(property: FirProperty) { - context.forPropertyDelegateAccessors(property, resolutionContext, callCompleter) { // Resolve delegate expression, after that, delegate will contain either expr.provideDelegate or expr if (property.isLocal) { @@ -282,7 +281,6 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor val finalSubstitutor = createFinalSubstitutor() - // Replace stub types with corresponding type variable types val stubTypeCompletionResultsWriter = FirStubTypeTransformer(finalSubstitutor) property.transformSingle(stubTypeCompletionResultsWriter, null) diff --git a/compiler/testData/diagnostics/tests/delegation/kt44843.fir.kt b/compiler/testData/diagnostics/tests/delegation/kt44843.fir.kt index 2e7b1057521..153b3c1f2df 100644 --- a/compiler/testData/diagnostics/tests/delegation/kt44843.fir.kt +++ b/compiler/testData/diagnostics/tests/delegation/kt44843.fir.kt @@ -1,13 +1,13 @@ // WITH_STDLIB // FILE: test.kt -val bar2 by bar2() +val bar2 by bar2() // FILE: lt/neworld/compiler/Foo.kt package lt.neworld.compiler class Foo { - val bar by bar() + val bar by bar() } // FILE: lt/neworld/compiler/bar/Bar.kt diff --git a/compiler/testData/diagnostics/tests/delegation/kt49477.fir.kt b/compiler/testData/diagnostics/tests/delegation/kt49477.fir.kt index 1e4e2b93591..45014c3ecde 100644 --- a/compiler/testData/diagnostics/tests/delegation/kt49477.fir.kt +++ b/compiler/testData/diagnostics/tests/delegation/kt49477.fir.kt @@ -8,7 +8,7 @@ inline fun Self property: KProperty1>): Delegate = TODO() class GitLabBuildProcessor: DatabaseEntity { - var processor by parent(GitLabChangesProcessor::buildProcessors) + var processor by parent(GitLabChangesProcessor::buildProcessors) } interface DatabaseEntity: Entity diff --git a/compiler/testData/diagnostics/tests/delegation/kt49477Error.fir.kt b/compiler/testData/diagnostics/tests/delegation/kt49477Error.fir.kt index 22ee3be0439..e99e8bdb576 100644 --- a/compiler/testData/diagnostics/tests/delegation/kt49477Error.fir.kt +++ b/compiler/testData/diagnostics/tests/delegation/kt49477Error.fir.kt @@ -9,7 +9,7 @@ inline fun Self property: KProperty1>): Delegate = TODO() class GitLabBuildProcessor: DatabaseEntity { - var processor by parent(GitLabChangesProcessor::buildProcessors) + var processor by parent(GitLabChangesProcessor::buildProcessors) } interface DatabaseEntity: Entity diff --git a/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/stubTypeReceiverRestriction.fir.kt b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/stubTypeReceiverRestriction.fir.kt index 0294509b82d..a6c6e70d8aa 100644 --- a/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/stubTypeReceiverRestriction.fir.kt +++ b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/stubTypeReceiverRestriction.fir.kt @@ -69,4 +69,4 @@ fun test6() { genericLambda { it.extension() } use(::extension) } -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/stubTypeReceiverRestrictionDisabled.fir.kt b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/stubTypeReceiverRestrictionDisabled.fir.kt index bd649fb47b2..c6325c478c9 100644 --- a/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/stubTypeReceiverRestrictionDisabled.fir.kt +++ b/compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/stubTypeReceiverRestrictionDisabled.fir.kt @@ -70,4 +70,4 @@ fun test6() { genericLambda { it.extension() } use(::extension) } -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/inference/delegates/kt50994.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/inference/delegates/kt50994.fir.kt index 3bbcab8e72f..88b67ef10c0 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/inference/delegates/kt50994.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/inference/delegates/kt50994.fir.kt @@ -1,10 +1,11 @@ +// FIR_DUMP // WITH_REFLECT import kotlin.properties.ReadWriteProperty import kotlin.reflect.KProperty1 class ProcessorWithParent : Entity { - var processor by parent(ProcessorWithChildren::processors) + var processor by parent(ProcessorWithChildren::processors) } class ProcessorWithChildren : Entity { diff --git a/compiler/testData/diagnostics/testsWithStdLib/inference/delegates/kt50994.fir.txt b/compiler/testData/diagnostics/testsWithStdLib/inference/delegates/kt50994.fir.txt new file mode 100644 index 00000000000..46cca0e6764 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/inference/delegates/kt50994.fir.txt @@ -0,0 +1,95 @@ +FILE: kt50994.fir.kt + public final class ProcessorWithParent : R|Entity| { + public constructor(): R|ProcessorWithParent| { + super() + } + + public final var processor: R|ProcessorWithChildren?|by this@R|/ProcessorWithParent|.R|/parent|(Q|ProcessorWithChildren|::R|/ProcessorWithChildren.processors|) + public get(): R|ProcessorWithChildren?| { + ^ this@R|/ProcessorWithParent|.D|/ProcessorWithParent.processor|.R|SubstitutionOverride|(this@R|/ProcessorWithParent|, ::R|/ProcessorWithParent.processor|) + } + public set(: R|ProcessorWithChildren?|): R|kotlin/Unit| { + this@R|/ProcessorWithParent|.D|/ProcessorWithParent.processor|.R|SubstitutionOverride|(this@R|/ProcessorWithParent|, ::R|/ProcessorWithParent.processor|, R|/processor|) + } + + } + public final class ProcessorWithChildren : R|Entity| { + public constructor(): R|ProcessorWithChildren| { + super() + } + + public final var processors: R|kotlin/collections/MutableCollection|by this@R|/ProcessorWithChildren|.#((Q|ProcessorWithParent|).R|kotlin/jvm/java|, Q|ProcessorWithParent|::#) + public get(): R|kotlin/collections/MutableCollection| { + ^ this@R|/ProcessorWithChildren|.D|/ProcessorWithChildren.processors|.R|SubstitutionOverride|>|(this@R|/ProcessorWithChildren|, ::R|/ProcessorWithChildren.processors|) + } + public set(: R|kotlin/collections/MutableCollection|): R|kotlin/Unit| { + this@R|/ProcessorWithChildren|.D|/ProcessorWithChildren.processors|.R|SubstitutionOverride|(this@R|/ProcessorWithChildren|, ::R|/ProcessorWithChildren.processors|, R|/processors|) + } + + } + public final class Processor2WithParent : R|Entity| { + public constructor(): R|Processor2WithParent| { + super() + } + + public final var processor: R|Processor2WithChildren?|by this@R|/Processor2WithParent|.R|/parent|(Q|Processor2WithChildren|::R|/Processor2WithChildren.processors|) + public get(): R|Processor2WithChildren?| { + ^ this@R|/Processor2WithParent|.D|/Processor2WithParent.processor|.R|SubstitutionOverride|(this@R|/Processor2WithParent|, ::R|/Processor2WithParent.processor|) + } + public set(: R|Processor2WithChildren?|): R|kotlin/Unit| { + this@R|/Processor2WithParent|.D|/Processor2WithParent.processor|.R|SubstitutionOverride|(this@R|/Processor2WithParent|, ::R|/Processor2WithParent.processor|, R|/processor|) + } + + } + public final class Processor2WithChildren : R|Entity| { + public constructor(): R|Processor2WithChildren| { + super() + } + + public final var processors: R|kotlin/collections/MutableCollection|by this@R|/Processor2WithChildren|.R|/children|((Q|Processor2WithParent|).R|kotlin/jvm/java|, Q|Processor2WithParent|::R|/Processor2WithParent.processor|) + public get(): R|kotlin/collections/MutableCollection| { + ^ this@R|/Processor2WithChildren|.D|/Processor2WithChildren.processors|.R|SubstitutionOverride|>|(this@R|/Processor2WithChildren|, ::R|/Processor2WithChildren.processors|) + } + public set(: R|kotlin/collections/MutableCollection|): R|kotlin/Unit| { + this@R|/Processor2WithChildren|.D|/Processor2WithChildren.processors|.R|SubstitutionOverride|(this@R|/Processor2WithChildren|, ::R|/Processor2WithChildren.processors|, R|/processors|) + } + + } + public final class Processor3WithParent : R|Entity| { + public constructor(): R|Processor3WithParent| { + super() + } + + public final var processor: R|Processor3WithChildren?|by this@R|/Processor3WithParent|.R|/parent|(Q|Processor3WithChildren|::R|/Processor3WithChildren.processors|) + public get(): R|Processor3WithChildren?| { + ^ this@R|/Processor3WithParent|.D|/Processor3WithParent.processor|.R|SubstitutionOverride|(this@R|/Processor3WithParent|, ::R|/Processor3WithParent.processor|) + } + public set(: R|Processor3WithChildren?|): R|kotlin/Unit| { + this@R|/Processor3WithParent|.D|/Processor3WithParent.processor|.R|SubstitutionOverride|(this@R|/Processor3WithParent|, ::R|/Processor3WithParent.processor|, R|/processor|) + } + + } + public final class Processor3WithChildren : R|Entity| { + public constructor(): R|Processor3WithChildren| { + super() + } + + public final var processors: R|kotlin/collections/MutableCollection|by this@R|/Processor3WithChildren|.R|/children|((Q|Processor3WithParent|).R|kotlin/jvm/java|, Q|Processor3WithParent|::R|/Processor3WithParent.processor|) + public get(): R|kotlin/collections/MutableCollection| { + ^ this@R|/Processor3WithChildren|.D|/Processor3WithChildren.processors|.R|SubstitutionOverride|>|(this@R|/Processor3WithChildren|, ::R|/Processor3WithChildren.processors|) + } + public set(: R|kotlin/collections/MutableCollection|): R|kotlin/Unit| { + this@R|/Processor3WithChildren|.D|/Processor3WithChildren.processors|.R|SubstitutionOverride|(this@R|/Processor3WithChildren|, ::R|/Processor3WithChildren.processors|, R|/processors|) + } + + } + public final inline fun R|SP|.parent(property: R|kotlin/reflect/KProperty1>|): R|Delegate| { + ^parent Null(null)!! + } + public final fun R|SC|.children(clazz: R|java/lang/Class|, property: R|kotlin/reflect/KProperty1|, name: R|kotlin/String| = R|/property|.R|SubstitutionOverride|): R|Delegate>| { + ^children Null(null)!! + } + public abstract interface Delegate : R|kotlin/properties/ReadWriteProperty| { + } + public abstract interface Entity : R|kotlin/Any| { + } diff --git a/compiler/testData/diagnostics/testsWithStdLib/inference/delegates/kt50994.kt b/compiler/testData/diagnostics/testsWithStdLib/inference/delegates/kt50994.kt index 15832df530a..0bb5bcd6966 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/inference/delegates/kt50994.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/inference/delegates/kt50994.kt @@ -1,3 +1,4 @@ +// FIR_DUMP // WITH_REFLECT import kotlin.properties.ReadWriteProperty