diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/j+k/SyntheticAfterFiltering.fir.txt b/compiler/fir/analysis-tests/testData/resolveWithStdlib/j+k/SyntheticAfterFiltering.fir.txt index c010c4bdbfe..ce3cfa0b1a5 100644 --- a/compiler/fir/analysis-tests/testData/resolveWithStdlib/j+k/SyntheticAfterFiltering.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/j+k/SyntheticAfterFiltering.fir.txt @@ -1,6 +1,6 @@ FILE: test.kt public final fun foo(tag: R|XmlTag|, name: R|kotlin/String|): R|kotlin/collections/List| { - lval result: R|kotlin/collections/List<@NoInfer XmlTag>| = R|/tag|.R|/PsiElement.children|.R|kotlin/collections/filterIsInstance|().R|kotlin/collections/filter|( = filter@fun (it: R|@NoInfer XmlTag|): R|kotlin/Boolean| { + lval result: R|kotlin/collections/List| = R|/tag|.R|/PsiElement.children|.R|kotlin/collections/filterIsInstance|().R|kotlin/collections/filter|( = filter@fun (it: R|@NoInfer XmlTag|): R|kotlin/Boolean| { ^ ==(R|/it|.R|/XmlTag.localName|, R|/name|) } ) diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/withInInitializer.fir.txt b/compiler/fir/analysis-tests/testData/resolveWithStdlib/withInInitializer.fir.txt index e60cb9712a6..8a5a4a84890 100644 --- a/compiler/fir/analysis-tests/testData/resolveWithStdlib/withInInitializer.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/withInInitializer.fir.txt @@ -19,13 +19,13 @@ FILE: withInInitializer.kt public final val data: R|First| = R|/First.First|(Int(42)) public get(): R|First| - public final val test: R|kotlin/collections/List<@NoInfer kotlin/Int>| = R|kotlin/with||>(this@R|/Second|.R|/Second.data|, = with@fun R|First|.(): R|kotlin/collections/List<@NoInfer kotlin/Int>| { + public final val test: R|kotlin/collections/List| = R|kotlin/with||>(this@R|/Second|.R|/Second.data|, = with@fun R|First|.(): R|kotlin/collections/List<@NoInfer kotlin/Int>| { ^ this@R|/Second|.R|/Second.list|.R|kotlin/collections/filterIsInstance|().R|kotlin/collections/filter|( = filter@fun (it: R|@NoInfer kotlin/Int|): R|kotlin/Boolean| { ^ ==(R|/it|, this@R|special/anonymous|.R|/First.member|) } ) } ) - public get(): R|kotlin/collections/List<@NoInfer kotlin/Int>| + public get(): R|kotlin/collections/List| } diff --git a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeAttributes.kt b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeAttributes.kt index 8ac7479165d..92181b98ad6 100644 --- a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeAttributes.kt +++ b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeAttributes.kt @@ -125,6 +125,11 @@ class ConeAttributes private constructor(attributes: List>) : A }) } + fun filterNecessaryToKeep(): ConeAttributes { + return if (all { it.keepInInferredDeclarationType }) this + else create(filter { it.keepInInferredDeclarationType }) + } + private inline fun perform(other: ConeAttributes, op: ConeAttribute<*>.(ConeAttribute<*>?) -> ConeAttribute<*>?): ConeAttributes { if (this.isEmpty() && other.isEmpty()) return this val attributes = mutableListOf>() diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/DeclarationApproximationUtils.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/DeclarationApproximationUtils.kt index 07323585813..279831ac9d4 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/DeclarationApproximationUtils.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/DeclarationApproximationUtils.kt @@ -30,10 +30,21 @@ fun FirTypeRef.approximateDeclarationType( } val preparedType = if (isLocal) baseType else baseType.substituteAlternativesInPublicType(session) - val approximatedType = session.typeApproximator.approximateToSuperType(preparedType, configuration) ?: preparedType + var approximatedType = session.typeApproximator.approximateToSuperType(preparedType, configuration) ?: preparedType + if (approximatedType.contains { type -> type.attributes.any { !it.keepInInferredDeclarationType } }) { + approximatedType = UnnecessaryAttributesRemover(session).substituteOrSelf(approximatedType) + } return this.withReplacedConeType(approximatedType).applyIf(stripEnhancedNullability) { withoutEnhancedNullability() } } +private class UnnecessaryAttributesRemover(session: FirSession) : AbstractConeSubstitutor(session.typeContext) { + override fun substituteType(type: ConeKotlinType): ConeKotlinType? { + val filteredAttributes = type.attributes.filterNecessaryToKeep() + return if (filteredAttributes === type.attributes) null + else type.withAttributes(filteredAttributes) + } +} + private fun ConeKotlinType.substituteAlternativesInPublicType(session: FirSession): ConeKotlinType { val substitutor = object : AbstractConeSubstitutor(session.typeContext) { override fun substituteType(type: ConeKotlinType): ConeKotlinType? { diff --git a/plugins/kotlinx-serialization/testData/firMembers/metaSerializable.fir.txt b/plugins/kotlinx-serialization/testData/firMembers/metaSerializable.fir.txt index 9f861303ad4..adb25dc8452 100644 --- a/plugins/kotlinx-serialization/testData/firMembers/metaSerializable.fir.txt +++ b/plugins/kotlinx-serialization/testData/firMembers/metaSerializable.fir.txt @@ -434,12 +434,12 @@ FILE: metaSerializable.kt lval reconstructed: R|Project2| = Q|kotlinx/serialization/json/Json|.R|kotlinx/serialization/json/Json.decodeFromString|(Q|Project2|.R|/Project2.Companion.serializer|(), R|/string|) R|kotlin/test/assertEquals|(String(name), R|/reconstructed|.R|/Project2.name|) R|kotlin/test/assertEquals|(String(lang), R|/reconstructed|.R|/Project2.language|) - lval info: R|@NoInfer MySerializableWithInfo| = Q|Project2|.R|/Project2.Companion.serializer|().R|SubstitutionOverride|.R|kotlinx/serialization/descriptors/SerialDescriptor.annotations|.R|kotlin/collections/filterIsInstance|().R|kotlin/collections/first|() + lval info: R|MySerializableWithInfo| = Q|Project2|.R|/Project2.Companion.serializer|().R|SubstitutionOverride|.R|kotlinx/serialization/descriptors/SerialDescriptor.annotations|.R|kotlin/collections/filterIsInstance|().R|kotlin/collections/first|() R|kotlin/test/assertEquals|(Int(123), R|/info|.R|/MySerializableWithInfo.value|) R|kotlin/test/assertEquals||>((Q|kotlin/String|), R|/info|.R|/MySerializableWithInfo.kclass|) } public final fun testMetaSerializableOnProperty(): R|kotlin/Unit| { - lval info: R|@NoInfer MySerializableWithInfo| = Q|Wrapper|.R|/Wrapper.Companion.serializer|().R|SubstitutionOverride|.R|kotlinx/serialization/descriptors/SerialDescriptor.getElementAnnotations|(Int(0)).R|kotlin/collections/filterIsInstance|().R|kotlin/collections/first|() + lval info: R|MySerializableWithInfo| = Q|Wrapper|.R|/Wrapper.Companion.serializer|().R|SubstitutionOverride|.R|kotlinx/serialization/descriptors/SerialDescriptor.getElementAnnotations|(Int(0)).R|kotlin/collections/filterIsInstance|().R|kotlin/collections/first|() R|kotlin/test/assertEquals|(Int(234), R|/info|.R|/MySerializableWithInfo.value|) R|kotlin/test/assertEquals||>((Q|kotlin/Int|), R|/info|.R|/MySerializableWithInfo.kclass|) } @@ -449,7 +449,7 @@ FILE: metaSerializable.kt lval reconstructed: R|Project3| = Q|kotlinx/serialization/json/Json|.R|kotlinx/serialization/json/Json.decodeFromString|(Q|Project3|.R|/Project3.Companion.serializer|(), R|/string|) R|kotlin/test/assertEquals|(String(name), R|/reconstructed|.R|/Project3.name|) R|kotlin/test/assertEquals|(String(lang), R|/reconstructed|.R|/Project3.language|) - lval info: R|@NoInfer MySerializableWithInfo| = Q|Project3|.R|/Project3.Companion.serializer|().R|SubstitutionOverride|.R|kotlinx/serialization/descriptors/SerialDescriptor.annotations|.R|kotlin/collections/filterIsInstance|().R|kotlin/collections/first|() + lval info: R|MySerializableWithInfo| = Q|Project3|.R|/Project3.Companion.serializer|().R|SubstitutionOverride|.R|kotlinx/serialization/descriptors/SerialDescriptor.annotations|.R|kotlin/collections/filterIsInstance|().R|kotlin/collections/first|() R|kotlin/test/assertEquals|(Int(123), R|/info|.R|/MySerializableWithInfo.value|) R|kotlin/test/assertEquals||>((Q|kotlin/String|), R|/info|.R|/MySerializableWithInfo.kclass|) } @@ -465,8 +465,8 @@ FILE: metaSerializable.kt lval serializerB: R|kotlinx/serialization/KSerializer| = Q|TestSealed.B|.R|/TestSealed.B.Companion.serializer|() R|kotlin/test/assertNotNull||>(R|/serializerA|) R|kotlin/test/assertNotNull||>(R|/serializerB|) - lval infoA: R|@NoInfer MySerializableWithInfo| = R|/serializerA|.R|SubstitutionOverride|.R|kotlinx/serialization/descriptors/SerialDescriptor.annotations|.R|kotlin/collections/filterIsInstance|().R|kotlin/collections/first|() - lval infoB: R|@NoInfer MySerializableWithInfo| = R|/serializerB|.R|SubstitutionOverride|.R|kotlinx/serialization/descriptors/SerialDescriptor.annotations|.R|kotlin/collections/filterIsInstance|().R|kotlin/collections/first|() + lval infoA: R|MySerializableWithInfo| = R|/serializerA|.R|SubstitutionOverride|.R|kotlinx/serialization/descriptors/SerialDescriptor.annotations|.R|kotlin/collections/filterIsInstance|().R|kotlin/collections/first|() + lval infoB: R|MySerializableWithInfo| = R|/serializerB|.R|SubstitutionOverride|.R|kotlinx/serialization/descriptors/SerialDescriptor.annotations|.R|kotlin/collections/filterIsInstance|().R|kotlin/collections/first|() R|kotlin/test/assertEquals|(Int(123), R|/infoA|.R|/MySerializableWithInfo.value|) R|kotlin/test/assertEquals||>((Q|kotlin/String|), R|/infoA|.R|/MySerializableWithInfo.kclass|) R|kotlin/test/assertEquals|(Int(123), R|/infoB|.R|/MySerializableWithInfo.value|) @@ -477,8 +477,8 @@ FILE: metaSerializable.kt lval serializerB: R|kotlinx/serialization/KSerializer| = Q|TestAbstract.B|.R|/TestAbstract.B.Companion.serializer|() R|kotlin/test/assertNotNull||>(R|/serializerA|) R|kotlin/test/assertNotNull||>(R|/serializerB|) - lval infoA: R|@NoInfer MySerializableWithInfo| = R|/serializerA|.R|SubstitutionOverride|.R|kotlinx/serialization/descriptors/SerialDescriptor.annotations|.R|kotlin/collections/filterIsInstance|().R|kotlin/collections/first|() - lval infoB: R|@NoInfer MySerializableWithInfo| = R|/serializerB|.R|SubstitutionOverride|.R|kotlinx/serialization/descriptors/SerialDescriptor.annotations|.R|kotlin/collections/filterIsInstance|().R|kotlin/collections/first|() + lval infoA: R|MySerializableWithInfo| = R|/serializerA|.R|SubstitutionOverride|.R|kotlinx/serialization/descriptors/SerialDescriptor.annotations|.R|kotlin/collections/filterIsInstance|().R|kotlin/collections/first|() + lval infoB: R|MySerializableWithInfo| = R|/serializerB|.R|SubstitutionOverride|.R|kotlinx/serialization/descriptors/SerialDescriptor.annotations|.R|kotlin/collections/filterIsInstance|().R|kotlin/collections/first|() R|kotlin/test/assertEquals|(Int(123), R|/infoA|.R|/MySerializableWithInfo.value|) R|kotlin/test/assertEquals||>((Q|kotlin/String|), R|/infoA|.R|/MySerializableWithInfo.kclass|) R|kotlin/test/assertEquals|(Int(123), R|/infoB|.R|/MySerializableWithInfo.value|) @@ -487,14 +487,14 @@ FILE: metaSerializable.kt public final fun testEnum(): R|kotlin/Unit| { lval serializer: R|kotlinx/serialization/KSerializer| = Q|TestEnum|.R|/TestEnum.Companion.serializer|() R|kotlin/test/assertNotNull||>(R|/serializer|) - lval info: R|@NoInfer MySerializableWithInfo| = R|/serializer|.R|SubstitutionOverride|.R|kotlinx/serialization/descriptors/SerialDescriptor.annotations|.R|kotlin/collections/filterIsInstance|().R|kotlin/collections/first|() + lval info: R|MySerializableWithInfo| = R|/serializer|.R|SubstitutionOverride|.R|kotlinx/serialization/descriptors/SerialDescriptor.annotations|.R|kotlin/collections/filterIsInstance|().R|kotlin/collections/first|() R|kotlin/test/assertEquals|(Int(123), R|/info|.R|/MySerializableWithInfo.value|) R|kotlin/test/assertEquals||>((Q|kotlin/String|), R|/info|.R|/MySerializableWithInfo.kclass|) } public final fun testObject(): R|kotlin/Unit| { lval serializer: R|kotlinx/serialization/KSerializer| = Q|TestObject|.R|/TestObject.serializer|() R|kotlin/test/assertNotNull||>(R|/serializer|) - lval info: R|@NoInfer MySerializableWithInfo| = R|/serializer|.R|SubstitutionOverride|.R|kotlinx/serialization/descriptors/SerialDescriptor.annotations|.R|kotlin/collections/filterIsInstance|().R|kotlin/collections/first|() + lval info: R|MySerializableWithInfo| = R|/serializer|.R|SubstitutionOverride|.R|kotlinx/serialization/descriptors/SerialDescriptor.annotations|.R|kotlin/collections/filterIsInstance|().R|kotlin/collections/first|() R|kotlin/test/assertEquals|(Int(123), R|/info|.R|/MySerializableWithInfo.value|) R|kotlin/test/assertEquals||>((Q|kotlin/String|), R|/info|.R|/MySerializableWithInfo.kclass|) }