From 56d817b49fb739f7adba2387f6afc388de952587 Mon Sep 17 00:00:00 2001 From: Irene Dea Date: Wed, 13 Oct 2021 14:37:31 -0700 Subject: [PATCH] Union type attributes for common super type calculation --- .../META-INF/extensions/compiler.xml | 3 + .../kotlin/fir/types/ConeTypeContext.kt | 2 +- .../kotlin/ir/types/IrTypeSystemContext.kt | 2 +- .../calls/NewCommonSuperTypeCalculator.kt | 2 +- .../PostponedArgumentInputTypesResolver.kt | 2 +- .../model/MutableConstraintStorage.kt | 6 +- .../kotlin/types/model/TypeSystemContext.kt | 6 +- .../kotlin/types/CompilerTypeAttributes.kt | 112 ------------------ .../jetbrains/kotlin/types/TypeAttributes.kt | 7 +- .../kotlin/types/TypeAttributesTranslator.kt | 25 +--- .../types/checker/ClassicTypeSystemContext.kt | 27 ++++- 11 files changed, 44 insertions(+), 150 deletions(-) delete mode 100644 core/descriptors/src/org/jetbrains/kotlin/types/CompilerTypeAttributes.kt diff --git a/compiler/cli/cli-common/resources/META-INF/extensions/compiler.xml b/compiler/cli/cli-common/resources/META-INF/extensions/compiler.xml index 3f0f1f336e0..7aa07b199d1 100644 --- a/compiler/cli/cli-common/resources/META-INF/extensions/compiler.xml +++ b/compiler/cli/cli-common/resources/META-INF/extensions/compiler.xml @@ -11,6 +11,9 @@ + diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt index 9479632ebae..f423b1aa213 100644 --- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt @@ -415,7 +415,7 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty return false } - override fun KotlinTypeMarker.getAnnotations(): List { + override fun KotlinTypeMarker.getAttributes(): List { require(this is ConeKotlinType) return attributes.toList() } 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 d78135e0a26..543ed606e1b 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 @@ -397,7 +397,7 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon override fun SimpleTypeMarker.isPrimitiveType(): Boolean = this is IrSimpleType && irTypePredicates_isPrimitiveType() - override fun KotlinTypeMarker.getAnnotations(): List { + override fun KotlinTypeMarker.getAttributes(): List { require(this is IrType) return this.annotations.map { object : AnnotationMarker, IrElement by it {} } } diff --git a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/NewCommonSuperTypeCalculator.kt b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/NewCommonSuperTypeCalculator.kt index ba5baa8eb53..4a8a07a2738 100644 --- a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/NewCommonSuperTypeCalculator.kt +++ b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/NewCommonSuperTypeCalculator.kt @@ -15,7 +15,7 @@ import org.jetbrains.kotlin.types.model.* object NewCommonSuperTypeCalculator { fun TypeSystemCommonSuperTypesContext.commonSuperType(types: List): KotlinTypeMarker { val maxDepth = types.maxOfOrNull { it.typeDepth() } ?: 0 - return commonSuperType(types, -maxDepth, true) + return commonSuperType(types, -maxDepth, true).replaceTypeAttributes(unionTypeAttributes(types)) } private fun TypeSystemCommonSuperTypesContext.commonSuperType( 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 039ccd215b6..06d4d9142f7 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 @@ -80,7 +80,7 @@ class PostponedArgumentInputTypesResolver( } } - val annotations = functionalTypesFromConstraints?.map { it.type.getAnnotations() }?.flatten()?.distinct() + val annotations = functionalTypesFromConstraints?.map { it.type.getAttributes() }?.flatten()?.distinct() val extensionFunctionTypePresentInConstraints = functionalTypesFromConstraints?.any { it.type.isExtensionFunctionType() } == true diff --git a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/model/MutableConstraintStorage.kt b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/model/MutableConstraintStorage.kt index 7ea2c276686..082aeeca589 100644 --- a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/model/MutableConstraintStorage.kt +++ b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/model/MutableConstraintStorage.kt @@ -139,7 +139,11 @@ class MutableVariableWithConstraints private constructor( return false return when (old.kind) { - ConstraintKind.EQUALITY -> true + ConstraintKind.EQUALITY -> { + with(context) { + old.type.getAttributes() == new.type.getAttributes() + } + } ConstraintKind.LOWER -> new.kind.isLower() ConstraintKind.UPPER -> new.kind.isUpper() } 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 4c14d266c8a..1e0cc26db0f 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 @@ -133,6 +133,10 @@ interface TypeSystemCommonSuperTypesContext : TypeSystemContext, TypeSystemTypeF * Used only in FIR */ fun TypeConstructorMarker.toErrorType(): SimpleTypeMarker + + fun unionTypeAttributes(types: List): List = emptyList() + + fun KotlinTypeMarker.replaceTypeAttributes(newAttributes: List): KotlinTypeMarker = this } // This interface is only used to declare that implementing class is supposed to be used as a TypeSystemInferenceExtensionContext component @@ -494,7 +498,7 @@ interface TypeSystemContext : TypeSystemOptimizationContext { fun SimpleTypeMarker.isPrimitiveType(): Boolean - fun KotlinTypeMarker.getAnnotations(): List + fun KotlinTypeMarker.getAttributes(): List fun substitutionSupertypePolicy(type: SimpleTypeMarker): TypeCheckerState.SupertypesPolicy diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/CompilerTypeAttributes.kt b/core/descriptors/src/org/jetbrains/kotlin/types/CompilerTypeAttributes.kt deleted file mode 100644 index 47321aadfa2..00000000000 --- a/core/descriptors/src/org/jetbrains/kotlin/types/CompilerTypeAttributes.kt +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2010-2021 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.types - -import org.jetbrains.kotlin.name.ClassId -import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.name.StandardClassIds -import kotlin.reflect.KClass - -object CompilerTypeAttributes { - object Exact : TypeAttribute() { - val ANNOTATION_CLASS_ID = ClassId(FqName("kotlin.internal"), Name.identifier("Exact")) - - override fun union(other: Exact?): Exact? = null - override fun intersect(other: Exact?): Exact? = null - override fun add(other: Exact?): Exact = this - - override fun isSubtypeOf(other: Exact?): Boolean = true - - override val key: KClass = Exact::class - - override fun toString(): String = "@Exact" - } - - object NoInfer : TypeAttribute() { - val ANNOTATION_CLASS_ID = ClassId(FqName("kotlin.internal"), Name.identifier("NoInfer")) - - override fun union(other: NoInfer?): NoInfer? = null - override fun intersect(other: NoInfer?): NoInfer? = null - override fun add(other: NoInfer?): NoInfer = this - override fun isSubtypeOf(other: NoInfer?): Boolean = true - - override val key: KClass = NoInfer::class - - override fun toString(): String = "@NoInfer" - } - - object EnhancedNullability : TypeAttribute() { - val ANNOTATION_CLASS_ID = StandardClassIds.Annotations.EnhancedNullability - - override fun union(other: EnhancedNullability?): EnhancedNullability? = other - override fun intersect(other: EnhancedNullability?): EnhancedNullability = this - override fun add(other: EnhancedNullability?): EnhancedNullability = this - - override fun isSubtypeOf(other: EnhancedNullability?): Boolean = true - - override val key: KClass = EnhancedNullability::class - - override fun toString(): String = "@EnhancedNullability" - } - - object ExtensionFunctionType : TypeAttribute() { - val ANNOTATION_CLASS_ID = ClassId(FqName("kotlin"), Name.identifier("ExtensionFunctionType")) - - override fun union(other: ExtensionFunctionType?): ExtensionFunctionType? = other - override fun intersect(other: ExtensionFunctionType?): ExtensionFunctionType = this - override fun add(other: ExtensionFunctionType?): ExtensionFunctionType = this - - override fun isSubtypeOf(other: ExtensionFunctionType?): Boolean = true - - override val key: KClass = ExtensionFunctionType::class - - override fun toString(): String = "@ExtensionFunctionType" - } - - object UnsafeVariance : TypeAttribute() { - val ANNOTATION_CLASS_ID = ClassId(FqName("kotlin"), Name.identifier("UnsafeVariance")) - - override fun union(other: UnsafeVariance?): UnsafeVariance? = null - override fun intersect(other: UnsafeVariance?): UnsafeVariance? = null - override fun add(other: UnsafeVariance?): UnsafeVariance = this - - override fun isSubtypeOf(other: UnsafeVariance?): Boolean = true - - override val key: KClass = UnsafeVariance::class - - override fun toString(): String = "@UnsafeVariance" - } - - val compilerAttributeByClassId: Map> = mapOf( - Exact.ANNOTATION_CLASS_ID to Exact, - NoInfer.ANNOTATION_CLASS_ID to NoInfer, - EnhancedNullability.ANNOTATION_CLASS_ID to EnhancedNullability, - ExtensionFunctionType.ANNOTATION_CLASS_ID to ExtensionFunctionType, - UnsafeVariance.ANNOTATION_CLASS_ID to UnsafeVariance - ) - - val compilerAttributeByFqName: Map> = compilerAttributeByClassId.mapKeys { it.key.asSingleFqName() } -} - -val TypeAttributes.exact: CompilerTypeAttributes.Exact? by TypeAttributes.attributeAccessor() -val TypeAttributes.noInfer: CompilerTypeAttributes.NoInfer? by TypeAttributes.attributeAccessor() -val TypeAttributes.enhancedNullability: CompilerTypeAttributes.EnhancedNullability? by TypeAttributes.attributeAccessor() -val TypeAttributes.extensionFunctionType: CompilerTypeAttributes.ExtensionFunctionType? by TypeAttributes.attributeAccessor() -val TypeAttributes.unsafeVarianceType: CompilerTypeAttributes.UnsafeVariance? by TypeAttributes.attributeAccessor() - -// ------------------------------------------------------------------ - -val TypeAttributes.hasEnhancedNullability: Boolean - get() = enhancedNullability != null - -// ------------------------------------------------------------------ - -val KotlinType.hasEnhancedNullability: Boolean - get() = attributes.enhancedNullability != null - -val KotlinType.isExtensionFunctionType: Boolean - get() = attributes.extensionFunctionType != null diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/TypeAttributes.kt b/core/descriptors/src/org/jetbrains/kotlin/types/TypeAttributes.kt index d71751ae2ba..36fcc2d8b6b 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/TypeAttributes.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/TypeAttributes.kt @@ -42,11 +42,6 @@ class TypeAttributes private constructor(attributes: List>) : A } val Empty: TypeAttributes = TypeAttributes(emptyList()) - val WithExtensionFunctionType: TypeAttributes = TypeAttributes(listOf(CompilerTypeAttributes.ExtensionFunctionType)) - - private val predefinedAttributes: Map, TypeAttributes> = mapOf( - CompilerTypeAttributes.EnhancedNullability.predefined() - ) private fun TypeAttribute<*>.predefined(): Pair, TypeAttributes> = this to TypeAttributes(this) @@ -87,7 +82,7 @@ class TypeAttributes private constructor(attributes: List>) : A @OptIn(ExperimentalStdlibApi::class) operator fun plus(attribute: TypeAttribute<*>): TypeAttributes { if (attribute in this) return this - if (isEmpty()) return predefinedAttributes[attribute] ?: TypeAttributes(attribute) + if (isEmpty()) return TypeAttributes(attribute) val newAttributes = buildList { addAll(this) add(attribute) diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/TypeAttributesTranslator.kt b/core/descriptors/src/org/jetbrains/kotlin/types/TypeAttributesTranslator.kt index 929830a6f05..c7ad12d99c3 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/TypeAttributesTranslator.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/TypeAttributesTranslator.kt @@ -5,9 +5,6 @@ package org.jetbrains.kotlin.types -import org.jetbrains.kotlin.builtins.DefaultBuiltIns -import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor -import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptorImpl import org.jetbrains.kotlin.descriptors.annotations.Annotations interface TypeAttributesTranslator { @@ -17,28 +14,10 @@ interface TypeAttributesTranslator { object DefaultTypeAttributesTranslator : TypeAttributesTranslator { override fun toAnnotations(attributes: TypeAttributes): Annotations { - val compilerAnnotations = CompilerTypeAttributes.compilerAttributeByFqName.mapNotNull { (fqName, attribute) -> - val annotationClass = DefaultBuiltIns.Instance.getBuiltInClassByFqName(fqName) - if (attribute in attributes) - AnnotationDescriptorImpl(annotationClass.defaultType, mapOf(), annotationClass.source) - else null - } - return Annotations.create(compilerAnnotations + attributes.customAnnotations) + return attributes.customAnnotations } override fun toAttributes(annotations: Annotations): TypeAttributes { - val customAnnotations = mutableListOf() - val compilerAttributes = mutableListOf>() - annotations.forEach { annotation -> - val compilerAttribute = CompilerTypeAttributes.compilerAttributeByFqName[annotation.fqName] - if (compilerAttribute != null) - compilerAttributes.add(compilerAttribute) - else - customAnnotations.add(annotation) - } - - return TypeAttributes.create( - compilerAttributes + CustomAnnotationTypeAttribute(customAnnotations) - ) + return TypeAttributes.create(listOf(CustomAnnotationTypeAttribute(annotations))) } } 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 d675decf34a..a5500c20c28 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/checker/ClassicTypeSystemContext.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/checker/ClassicTypeSystemContext.kt @@ -533,7 +533,12 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSy } @Suppress("UNCHECKED_CAST") - return KotlinTypeFactory.simpleType(resultingAnnotations, constructor, arguments as List, nullable) + return KotlinTypeFactory.simpleType( + DefaultTypeAttributesTranslator.toAttributes(resultingAnnotations), + constructor, + arguments as List, + nullable + ) } override fun createTypeArgument(type: KotlinTypeMarker, variance: TypeVariance): TypeArgumentMarker { @@ -634,6 +639,22 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSy return IntegerLiteralTypeConstructor.findCommonSuperType(explicitSupertypes) } + override fun unionTypeAttributes(types: List): List { + @Suppress("UNCHECKED_CAST") + types as List + return types.map { it.unwrap().attributes }.reduce { x, y -> x.union(y) }.toList() + } + + override fun KotlinTypeMarker.replaceTypeAttributes(newAttributes: List): KotlinTypeMarker { + require(this is KotlinType) + val typeAttributes = newAttributes.filterIsInstance>() + require(typeAttributes.size == newAttributes.size) + if (newAttributes.isEmpty()) return this + return this.unwrap().replaceAttributes( + TypeAttributes.create(typeAttributes) + ) + } + override fun TypeConstructorMarker.isError(): Boolean { require(this is TypeConstructor, this::errorMessage) return ErrorUtils.isError(declarationDescriptor) @@ -649,9 +670,9 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSy return KotlinBuiltIns.isPrimitiveType(this) } - override fun KotlinTypeMarker.getAnnotations(): List { + override fun KotlinTypeMarker.getAttributes(): List { require(this is KotlinType, this::errorMessage) - return this.annotations.toList() + return this.attributes.toList() } override fun captureFromExpression(type: KotlinTypeMarker): KotlinTypeMarker? {