[FIR] do not copy annotations during type propagation
We should share the original instance to be able to later resolve it in the original context. This commit returns the KT-60387 problem, but the root cause (concurrent modification) will be fixed in the context of KT-63042 ^KT-63042
This commit is contained in:
committed by
Space Team
parent
69559689fd
commit
264a151676
+1
-1
@@ -32,7 +32,7 @@ FILE: [ResolvedTo(IMPORTS)] lambdaAsSAMInterfaceWithAnnotation.kt
|
||||
public final const [ResolvedTo(IMPLICIT_TYPES_BODY_RESOLVE)] val constant: R|kotlin/Int| = Int(0)
|
||||
public [ResolvedTo(IMPLICIT_TYPES_BODY_RESOLVE)] get(): R|kotlin/Int|
|
||||
public abstract fun [ResolvedTo(STATUS)] interface Foo : R|kotlin/Any| {
|
||||
public abstract [ResolvedTo(STATUS)] fun foo([ResolvedTo(STATUS)] a: R|@R|foo/Anno|(<strcat>(String(foo param type ), R|foo/constant|)) foo/Arg|): R|@R|foo/Anno|(<strcat>(String(foo return type ), R|foo/constant|)) foo/Arg|
|
||||
public abstract [ResolvedTo(STATUS)] fun foo([ResolvedTo(STATUS)] a: R|@R|foo/Anno|(position = <strcat>(String(foo param type ), R|foo/constant|)) foo/Arg|): R|@R|foo/Anno|(position = <strcat>(String(foo return type ), R|foo/constant|)) foo/Arg|
|
||||
|
||||
}
|
||||
public final [ResolvedTo(CONTRACTS)] fun testMe([ResolvedTo(CONTRACTS)] f: R|@R|foo/Anno|(<strcat>(String(testMe param type ), constant#)) foo/Foo|): R|kotlin/Unit| {
|
||||
|
||||
Vendored
+2
-2
@@ -200,8 +200,8 @@ FILE: [ResolvedTo(IMPORTS)] anonymousFunctionWithAnnotatedParameter.kt
|
||||
public [ResolvedTo(STATUS)] [ContainingClassKey=Anno] get(): R|kotlin/String|
|
||||
|
||||
}
|
||||
public final [ResolvedTo(CONTRACTS)] val nullablePropertyWithAnnotatedType: R|@R|Anno|(String(outer)) kotlin/collections/List<@R|Anno|(String(middle)) kotlin/collections/List<@R|Anno|(String(inner)) kotlin/Int>>?|
|
||||
public [ResolvedTo(CONTRACTS)] get(): R|@R|Anno|(String(outer)) kotlin/collections/List<@R|Anno|(String(middle)) kotlin/collections/List<@R|Anno|(String(inner)) kotlin/Int>>?| {
|
||||
public final [ResolvedTo(CONTRACTS)] val nullablePropertyWithAnnotatedType: R|@R|Anno|(message = String(outer)) kotlin/collections/List<@R|Anno|(message = String(middle)) kotlin/collections/List<@R|Anno|(message = String(inner)) kotlin/Int>>?|
|
||||
public [ResolvedTo(CONTRACTS)] get(): R|@R|Anno|(message = String(outer)) kotlin/collections/List<@R|Anno|(message = String(middle)) kotlin/collections/List<@R|Anno|(message = String(inner)) kotlin/Int>>?| {
|
||||
^ Null(null)
|
||||
}
|
||||
public final [ResolvedTo(BODY_RESOLVE)] val propertyToResolve: R|kotlin/String|
|
||||
|
||||
Vendored
+3
-3
@@ -200,13 +200,13 @@ FILE: [ResolvedTo(IMPORTS)] anonymousFunctionWithAnnotatedParameter2.kt
|
||||
public [ResolvedTo(STATUS)] [ContainingClassKey=Anno] get(): R|kotlin/String|
|
||||
|
||||
}
|
||||
public final [ResolvedTo(CONTRACTS)] val nullablePropertyWithAnnotatedType: R|@R|Anno|(String(outer)) kotlin/collections/List<@R|Anno|(String(middle)) kotlin/collections/List<@R|Anno|(String(inner)) kotlin/Int>>?|
|
||||
public [ResolvedTo(CONTRACTS)] get(): R|@R|Anno|(String(outer)) kotlin/collections/List<@R|Anno|(String(middle)) kotlin/collections/List<@R|Anno|(String(inner)) kotlin/Int>>?| {
|
||||
public final [ResolvedTo(CONTRACTS)] val nullablePropertyWithAnnotatedType: R|@R|Anno|(message = String(outer)) kotlin/collections/List<@R|Anno|(message = String(middle)) kotlin/collections/List<@R|Anno|(message = String(inner)) kotlin/Int>>?|
|
||||
public [ResolvedTo(CONTRACTS)] get(): R|@R|Anno|(message = String(outer)) kotlin/collections/List<@R|Anno|(message = String(middle)) kotlin/collections/List<@R|Anno|(message = String(inner)) kotlin/Int>>?| {
|
||||
^ Null(null)
|
||||
}
|
||||
public final [ResolvedTo(BODY_RESOLVE)] val propertyToResolve: R|kotlin/String|
|
||||
public [ResolvedTo(BODY_RESOLVE)] get(): R|kotlin/String| {
|
||||
^ R|/nullablePropertyWithAnnotatedType|.R|kotlin/let|<R|@R|Anno|(String(outer)) kotlin/collections/List<@R|Anno|(String(middle)) kotlin/collections/List<@R|Anno|(String(inner)) kotlin/Int>>?|, R|kotlin/String|>(<L> = [ResolvedTo(BODY_RESOLVE)] [MatchingParameterFunctionTypeKey=kotlin/Function1<T, R>] let@fun <anonymous>([ResolvedTo(BODY_RESOLVE)] it: R|@R|Anno|(message = String(outer)) kotlin/collections/List<@R|Anno|(message = String(middle)) kotlin/collections/List<@R|Anno|(message = String(inner)) kotlin/Int>>?|): R|kotlin/String| <inline=Inline, kind=EXACTLY_ONCE> {
|
||||
^ R|/nullablePropertyWithAnnotatedType|.R|kotlin/let|<R|@R|Anno|(message = String(outer)) kotlin/collections/List<@R|Anno|(message = String(middle)) kotlin/collections/List<@R|Anno|(message = String(inner)) kotlin/Int>>?|, R|kotlin/String|>(<L> = [ResolvedTo(BODY_RESOLVE)] [MatchingParameterFunctionTypeKey=kotlin/Function1<T, R>] let@fun <anonymous>([ResolvedTo(BODY_RESOLVE)] it: R|@R|Anno|(message = String(outer)) kotlin/collections/List<@R|Anno|(message = String(middle)) kotlin/collections/List<@R|Anno|(message = String(inner)) kotlin/Int>>?|): R|kotlin/String| <inline=Inline, kind=EXACTLY_ONCE> {
|
||||
^ <strcat>(String( (), R|<local>/it|, String()))
|
||||
}
|
||||
)
|
||||
|
||||
Vendored
+4
-3
@@ -282,14 +282,14 @@ FILE: [ResolvedTo(IMPORTS)] anonymousFunctionWithAnnotatedParameter2Script.kts
|
||||
|
||||
}
|
||||
|
||||
public final [ResolvedTo(CONTRACTS)] val nullablePropertyWithAnnotatedType: R|@R|Anno|(String(outer)) kotlin/collections/List<@R|Anno|(String(middle)) kotlin/collections/List<@R|Anno|(String(inner)) kotlin/Int>>?|
|
||||
public [ResolvedTo(CONTRACTS)] get(): R|@R|Anno|(String(outer)) kotlin/collections/List<@R|Anno|(String(middle)) kotlin/collections/List<@R|Anno|(String(inner)) kotlin/Int>>?| {
|
||||
public final [ResolvedTo(CONTRACTS)] val nullablePropertyWithAnnotatedType: R|@R|Anno|(message = String(outer)) kotlin/collections/List<@R|Anno|(message = String(middle)) kotlin/collections/List<@R|Anno|(message = String(inner)) kotlin/Int>>?|
|
||||
public [ResolvedTo(CONTRACTS)] get(): R|@R|Anno|(message = String(outer)) kotlin/collections/List<@R|Anno|(message = String(middle)) kotlin/collections/List<@R|Anno|(message = String(inner)) kotlin/Int>>?| {
|
||||
^ Null(null)
|
||||
}
|
||||
|
||||
public final [ResolvedTo(BODY_RESOLVE)] val propertyToResolve: R|kotlin/String|
|
||||
public [ResolvedTo(BODY_RESOLVE)] get(): R|kotlin/String| {
|
||||
^ R|/nullablePropertyWithAnnotatedType|.R|kotlin/let|<R|@R|Anno|(String(outer)) kotlin/collections/List<@R|Anno|(String(middle)) kotlin/collections/List<@R|Anno|(String(inner)) kotlin/Int>>?|, R|kotlin/String|>(<L> = [ResolvedTo(BODY_RESOLVE)] [MatchingParameterFunctionTypeKey=kotlin/Function1<T, R>] let@fun <anonymous>([ResolvedTo(BODY_RESOLVE)] it: R|@R|Anno|(message = String(outer)) kotlin/collections/List<@R|Anno|(message = String(middle)) kotlin/collections/List<@R|Anno|(message = String(inner)) kotlin/Int>>?|): R|kotlin/String| <inline=Inline, kind=EXACTLY_ONCE> {
|
||||
^ R|/nullablePropertyWithAnnotatedType|.R|kotlin/let|<R|@R|Anno|(message = String(outer)) kotlin/collections/List<@R|Anno|(message = String(middle)) kotlin/collections/List<@R|Anno|(message = String(inner)) kotlin/Int>>?|, R|kotlin/String|>(<L> = [ResolvedTo(BODY_RESOLVE)] [MatchingParameterFunctionTypeKey=kotlin/Function1<T, R>] let@fun <anonymous>([ResolvedTo(BODY_RESOLVE)] it: R|@R|Anno|(message = String(outer)) kotlin/collections/List<@R|Anno|(message = String(middle)) kotlin/collections/List<@R|Anno|(message = String(inner)) kotlin/Int>>?|): R|kotlin/String| <inline=Inline, kind=EXACTLY_ONCE> {
|
||||
^ <strcat>(String( (), R|<local>/it|, String()))
|
||||
}
|
||||
)
|
||||
@@ -324,3 +324,4 @@ FILE: [ResolvedTo(BODY_RESOLVE)] anonymousFunctionWithAnnotatedParameter2Script.
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
+6
-6
@@ -158,8 +158,8 @@ FILE: [ResolvedTo(IMPORTS)] anonymousFunctionWithAnnotatedParameterOnImplicitTyp
|
||||
public [ResolvedTo(STATUS)] [ContainingClassKey=Anno] get(): R|kotlin/String|
|
||||
|
||||
}
|
||||
public final [ResolvedTo(CONTRACTS)] val nullablePropertyWithAnnotatedType: R|@R|Anno|(String(str)) kotlin/String?|
|
||||
public [ResolvedTo(CONTRACTS)] get(): R|@R|Anno|(String(str)) kotlin/String?| {
|
||||
public final [ResolvedTo(CONTRACTS)] val nullablePropertyWithAnnotatedType: R|@R|Anno|(message = String(str)) kotlin/String?|
|
||||
public [ResolvedTo(CONTRACTS)] get(): R|@R|Anno|(message = String(str)) kotlin/String?| {
|
||||
^ Null(null)
|
||||
}
|
||||
public final [ResolvedTo(IMPLICIT_TYPES_BODY_RESOLVE)] val propertyToResolve: R|kotlin/String|
|
||||
@@ -181,8 +181,8 @@ FILE: [ResolvedTo(IMPORTS)] anonymousFunctionWithAnnotatedParameterOnImplicitTyp
|
||||
public [ResolvedTo(STATUS)] [ContainingClassKey=Anno] get(): R|kotlin/String|
|
||||
|
||||
}
|
||||
public final [ResolvedTo(CONTRACTS)] val nullablePropertyWithAnnotatedType: R|@R|Anno|(String(str)) kotlin/String?|
|
||||
public [ResolvedTo(CONTRACTS)] get(): R|@R|Anno|(String(str)) kotlin/String?| {
|
||||
public final [ResolvedTo(CONTRACTS)] val nullablePropertyWithAnnotatedType: R|@R|Anno|(message = String(str)) kotlin/String?|
|
||||
public [ResolvedTo(CONTRACTS)] get(): R|@R|Anno|(message = String(str)) kotlin/String?| {
|
||||
^ Null(null)
|
||||
}
|
||||
public final [ResolvedTo(ANNOTATION_ARGUMENTS)] val propertyToResolve: R|kotlin/String|
|
||||
@@ -204,8 +204,8 @@ FILE: [ResolvedTo(IMPORTS)] anonymousFunctionWithAnnotatedParameterOnImplicitTyp
|
||||
public [ResolvedTo(STATUS)] [ContainingClassKey=Anno] get(): R|kotlin/String|
|
||||
|
||||
}
|
||||
public final [ResolvedTo(CONTRACTS)] val nullablePropertyWithAnnotatedType: R|@R|Anno|(String(str)) kotlin/String?|
|
||||
public [ResolvedTo(CONTRACTS)] get(): R|@R|Anno|(String(str)) kotlin/String?| {
|
||||
public final [ResolvedTo(CONTRACTS)] val nullablePropertyWithAnnotatedType: R|@R|Anno|(message = String(str)) kotlin/String?|
|
||||
public [ResolvedTo(CONTRACTS)] get(): R|@R|Anno|(message = String(str)) kotlin/String?| {
|
||||
^ Null(null)
|
||||
}
|
||||
public final [ResolvedTo(BODY_RESOLVE)] val propertyToResolve: R|kotlin/String|
|
||||
|
||||
+7
-6
@@ -226,8 +226,8 @@ FILE: [ResolvedTo(IMPORTS)] anonymousFunctionWithAnnotatedParameterOnImplicitTyp
|
||||
|
||||
}
|
||||
|
||||
public final [ResolvedTo(CONTRACTS)] val nullablePropertyWithAnnotatedType: R|@R|Anno|(String(str)) kotlin/String?|
|
||||
public [ResolvedTo(CONTRACTS)] get(): R|@R|Anno|(String(str)) kotlin/String?| {
|
||||
public final [ResolvedTo(CONTRACTS)] val nullablePropertyWithAnnotatedType: R|@R|Anno|(message = String(str)) kotlin/String?|
|
||||
public [ResolvedTo(CONTRACTS)] get(): R|@R|Anno|(message = String(str)) kotlin/String?| {
|
||||
^ Null(null)
|
||||
}
|
||||
|
||||
@@ -256,8 +256,8 @@ FILE: [ResolvedTo(IMPORTS)] anonymousFunctionWithAnnotatedParameterOnImplicitTyp
|
||||
|
||||
}
|
||||
|
||||
public final [ResolvedTo(CONTRACTS)] val nullablePropertyWithAnnotatedType: R|@R|Anno|(String(str)) kotlin/String?|
|
||||
public [ResolvedTo(CONTRACTS)] get(): R|@R|Anno|(String(str)) kotlin/String?| {
|
||||
public final [ResolvedTo(CONTRACTS)] val nullablePropertyWithAnnotatedType: R|@R|Anno|(message = String(str)) kotlin/String?|
|
||||
public [ResolvedTo(CONTRACTS)] get(): R|@R|Anno|(message = String(str)) kotlin/String?| {
|
||||
^ Null(null)
|
||||
}
|
||||
|
||||
@@ -286,8 +286,8 @@ FILE: [ResolvedTo(IMPORTS)] anonymousFunctionWithAnnotatedParameterOnImplicitTyp
|
||||
|
||||
}
|
||||
|
||||
public final [ResolvedTo(CONTRACTS)] val nullablePropertyWithAnnotatedType: R|@R|Anno|(String(str)) kotlin/String?|
|
||||
public [ResolvedTo(CONTRACTS)] get(): R|@R|Anno|(String(str)) kotlin/String?| {
|
||||
public final [ResolvedTo(CONTRACTS)] val nullablePropertyWithAnnotatedType: R|@R|Anno|(message = String(str)) kotlin/String?|
|
||||
public [ResolvedTo(CONTRACTS)] get(): R|@R|Anno|(message = String(str)) kotlin/String?| {
|
||||
^ Null(null)
|
||||
}
|
||||
|
||||
@@ -328,3 +328,4 @@ FILE: [ResolvedTo(BODY_RESOLVE)] anonymousFunctionWithAnnotatedParameterOnImplic
|
||||
}
|
||||
) } ?: String()
|
||||
}
|
||||
|
||||
|
||||
Vendored
+3
-2
@@ -282,8 +282,8 @@ FILE: [ResolvedTo(IMPORTS)] anonymousFunctionWithAnnotatedParameterScript.kts
|
||||
|
||||
}
|
||||
|
||||
public final [ResolvedTo(CONTRACTS)] val nullablePropertyWithAnnotatedType: R|@R|Anno|(String(outer)) kotlin/collections/List<@R|Anno|(String(middle)) kotlin/collections/List<@R|Anno|(String(inner)) kotlin/Int>>?|
|
||||
public [ResolvedTo(CONTRACTS)] get(): R|@R|Anno|(String(outer)) kotlin/collections/List<@R|Anno|(String(middle)) kotlin/collections/List<@R|Anno|(String(inner)) kotlin/Int>>?| {
|
||||
public final [ResolvedTo(CONTRACTS)] val nullablePropertyWithAnnotatedType: R|@R|Anno|(message = String(outer)) kotlin/collections/List<@R|Anno|(message = String(middle)) kotlin/collections/List<@R|Anno|(message = String(inner)) kotlin/Int>>?|
|
||||
public [ResolvedTo(CONTRACTS)] get(): R|@R|Anno|(message = String(outer)) kotlin/collections/List<@R|Anno|(message = String(middle)) kotlin/collections/List<@R|Anno|(message = String(inner)) kotlin/Int>>?| {
|
||||
^ Null(null)
|
||||
}
|
||||
|
||||
@@ -324,3 +324,4 @@ FILE: [ResolvedTo(BODY_RESOLVE)] anonymousFunctionWithAnnotatedParameterScript.k
|
||||
}
|
||||
) } ?: String()
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -294,8 +294,8 @@ FILE: [ResolvedTo(IMPORTS)] declaration.kt
|
||||
public [ResolvedTo(STATUS)] [ContainingClassKey=Anno] get(): R|kotlin/String|
|
||||
|
||||
}
|
||||
public final [ResolvedTo(CONTRACTS)] val nullablePropertyWithAnnotatedType: R|@R|Anno|(R|/privateConstant<HIDDEN: /privateConstant is invisible>#|) kotlin/collections/List<@R|Anno|(R|/internalConstant<HIDDEN: /internalConstant is invisible>#|) kotlin/collections/List<@R|Anno|(R|/regularConstant|) kotlin/Int>>?|
|
||||
public [ResolvedTo(CONTRACTS)] get(): R|@R|Anno|(R|/privateConstant<HIDDEN: /privateConstant is invisible>#|) kotlin/collections/List<@R|Anno|(R|/internalConstant<HIDDEN: /internalConstant is invisible>#|) kotlin/collections/List<@R|Anno|(R|/regularConstant|) kotlin/Int>>?| {
|
||||
public final [ResolvedTo(CONTRACTS)] val nullablePropertyWithAnnotatedType: R|@R|Anno|(message = R|/privateConstant<HIDDEN: /privateConstant is invisible>#|) kotlin/collections/List<@R|Anno|(message = R|/internalConstant<HIDDEN: /internalConstant is invisible>#|) kotlin/collections/List<@R|Anno|(message = R|/regularConstant|) kotlin/Int>>?|
|
||||
public [ResolvedTo(CONTRACTS)] get(): R|@R|Anno|(message = R|/privateConstant<HIDDEN: /privateConstant is invisible>#|) kotlin/collections/List<@R|Anno|(message = R|/internalConstant<HIDDEN: /internalConstant is invisible>#|) kotlin/collections/List<@R|Anno|(message = R|/regularConstant|) kotlin/Int>>?| {
|
||||
^ Null(null)
|
||||
}
|
||||
|
||||
|
||||
@@ -106,89 +106,6 @@ fun ConeDynamicType.Companion.create(
|
||||
session.builtinTypes.nullableAnyType.type.withAttributes(attributes),
|
||||
)
|
||||
|
||||
/**
|
||||
* This call is required if you want to use a type with annotations that are linked to a declaration from this declaration inside another
|
||||
* to avoid concurrent modification problems (see KT-60387).
|
||||
*
|
||||
* Otherwise, those annotations can be transformed from different threads simultaneously that is error-prone.
|
||||
* Example:
|
||||
* ```kotlin
|
||||
* val declaration: @Anno("outer") Int? get() = null
|
||||
* val anotherDeclaration: String get() = declaration?.let { "$it" }.toString()
|
||||
* ```
|
||||
* here for `declaration?.let { "$it" }` will be created an anonymous function with argument that
|
||||
* will have the same type as the return type of `declaration`.
|
||||
* So, now we have 2 possible scenarios:
|
||||
*
|
||||
* Wrong case 1 – The type was inserted to a new type ref as it is.
|
||||
* This means that a type reference from `declaration` and from the anonymous lambda will have the same instance of `Anno`.
|
||||
* Now we resole `anotherDeclaration` to [FirResolvePhase.BODY_RESOLVE] phase
|
||||
* and as a result we will have resolved annotation arguments in the type.
|
||||
* At the same time, `declaration` can be still in [FirResolvePhase.CONTRACTS] phase, because no one called a resolution yet.
|
||||
* So now imagine a situation when one thread (1) wants to read annotation arguments from the fully resolved anonymous function,
|
||||
* and another thread (2) wants to resolve `declaration` to [FirResolvePhase.ANNOTATION_ARGUMENTS] phase.
|
||||
* As a result, we will have a moment there thread 2 will replace arguments with a lazy expression
|
||||
* to be sure that we will have a safe basis for resolution (see StateKeeper concept in LL FIR).
|
||||
* And thread 1 will see unexpected unresolved annotation arguments in fully resolved function, because those type references
|
||||
* use the same instance of the type (`FirArgumentListImpl` cannot be cast to `FirResolvedArgumentList`).
|
||||
* So we lost here.
|
||||
*
|
||||
* Right case 2 – The type was "copied" by [independentInstance].
|
||||
* In this case, `declaration` and `anotherDeclaration` will have different instances of one `@Anno("outer") Int?` type.
|
||||
* This means that we can't come to a situation where we can modify a fully resolved annotation from another thread.
|
||||
*
|
||||
* @return an instance of a type that has no annotations associated with any declaration,
|
||||
* so it won't be changed from LL FIR lazy transformers concurrently
|
||||
*
|
||||
* @see CustomAnnotationTypeAttribute.independentInstance
|
||||
*/
|
||||
@OptIn(DynamicTypeConstructor::class)
|
||||
fun ConeKotlinType.independentInstance(): ConeKotlinType = if (this is ConeFlexibleType) {
|
||||
val newLowerBound = lowerBound.independentInstance() as ConeSimpleKotlinType
|
||||
val newUpperBound = upperBound.independentInstance() as ConeSimpleKotlinType
|
||||
if (newLowerBound !== lowerBound || newUpperBound !== upperBound) {
|
||||
when (this) {
|
||||
is ConeRawType -> ConeRawType.create(newLowerBound, newUpperBound)
|
||||
is ConeDynamicType -> ConeDynamicType(newLowerBound, newUpperBound)
|
||||
else -> ConeFlexibleType(newLowerBound, newUpperBound)
|
||||
}
|
||||
} else {
|
||||
this
|
||||
}
|
||||
} else {
|
||||
instanceWithIndependentArguments().instanceWithIndependentAnnotations()
|
||||
}
|
||||
|
||||
private fun ConeKotlinType.instanceWithIndependentArguments(): ConeKotlinType {
|
||||
val typeProjections = typeArguments
|
||||
if (typeProjections.isEmpty()) return this
|
||||
|
||||
var argumentsChanged = false
|
||||
val newArguments = type.typeArguments.map { originalArgument ->
|
||||
if (originalArgument !is ConeKotlinType)
|
||||
originalArgument
|
||||
else
|
||||
originalArgument.independentInstance().also {
|
||||
if (it !== originalArgument) {
|
||||
argumentsChanged = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return if (argumentsChanged) withArguments(newArguments.toTypedArray()) else this
|
||||
}
|
||||
|
||||
private fun ConeKotlinType.instanceWithIndependentAnnotations(): ConeKotlinType {
|
||||
val custom = attributes.custom ?: return this
|
||||
val newAnnotations = custom.independentInstance()
|
||||
if (newAnnotations === custom) {
|
||||
return this
|
||||
}
|
||||
|
||||
val newAttributes = attributes.remove(custom).plus(newAnnotations)
|
||||
return withAttributes(newAttributes)
|
||||
}
|
||||
|
||||
fun ConeKotlinType.makeConeTypeDefinitelyNotNullOrNotNull(
|
||||
typeContext: ConeTypeContext,
|
||||
avoidComprehensiveCheck: Boolean = false,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Copyright 2010-2023 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.
|
||||
*/
|
||||
|
||||
@@ -476,10 +476,9 @@ fun FirCheckedSafeCallSubject.propagateTypeFromOriginalReceiver(
|
||||
?.coneTypeSafe<ConeKotlinType>()
|
||||
?: nullableReceiverExpression.resolvedType
|
||||
|
||||
val expandedReceiverType = receiverType.fullyExpandedType(session)
|
||||
val updatedReceiverType = expandedReceiverType.makeConeTypeDefinitelyNotNullOrNotNull(session.typeContext).independentInstance()
|
||||
replaceConeTypeOrNull(updatedReceiverType)
|
||||
session.lookupTracker?.recordTypeResolveAsLookup(updatedReceiverType, source, file.source)
|
||||
val expandedReceiverType = receiverType.fullyExpandedType(session).makeConeTypeDefinitelyNotNullOrNotNull(session.typeContext)
|
||||
replaceConeTypeOrNull(expandedReceiverType)
|
||||
session.lookupTracker?.recordTypeResolveAsLookup(expandedReceiverType, source, file.source)
|
||||
}
|
||||
|
||||
fun FirSafeCallExpression.propagateTypeFromQualifiedAccessAfterNullCheck(
|
||||
@@ -500,9 +499,8 @@ fun FirSafeCallExpression.propagateTypeFromQualifiedAccessAfterNullCheck(
|
||||
}
|
||||
}
|
||||
|
||||
val independentInstance = resultingType.independentInstance()
|
||||
replaceConeTypeOrNull(independentInstance)
|
||||
session.lookupTracker?.recordTypeResolveAsLookup(independentInstance, source, file.source)
|
||||
replaceConeTypeOrNull(resultingType)
|
||||
session.lookupTracker?.recordTypeResolveAsLookup(resultingType, source, file.source)
|
||||
}
|
||||
|
||||
fun FirAnnotation.getCorrespondingClassSymbolOrNull(session: FirSession): FirRegularClassSymbol? {
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Copyright 2010-2023 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.
|
||||
*/
|
||||
|
||||
@@ -110,7 +110,7 @@ class PostponedArgumentsAnalyzer(
|
||||
val stubsForPostponedVariables = c.bindingStubsForPostponedVariables()
|
||||
val currentSubstitutor = c.buildCurrentSubstitutor(stubsForPostponedVariables.mapKeys { it.key.freshTypeConstructor(c) })
|
||||
|
||||
fun substitute(type: ConeKotlinType) = (currentSubstitutor.safeSubstitute(c, type) as ConeKotlinType).independentInstance()
|
||||
fun substitute(type: ConeKotlinType) = currentSubstitutor.safeSubstitute(c, type) as ConeKotlinType
|
||||
|
||||
val receiver = lambda.receiver?.let(::substitute)
|
||||
val contextReceivers = lambda.contextReceivers.map(::substitute)
|
||||
|
||||
@@ -6,9 +6,6 @@
|
||||
package org.jetbrains.kotlin.fir.types
|
||||
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
|
||||
import org.jetbrains.kotlin.fir.expressions.builder.buildAnnotationCallCopy
|
||||
import org.jetbrains.kotlin.fir.expressions.builder.buildAnnotationCopy
|
||||
import org.jetbrains.kotlin.fir.render
|
||||
import org.jetbrains.kotlin.fir.renderer.FirRenderer
|
||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||
@@ -63,27 +60,6 @@ class CustomAnnotationTypeAttribute(
|
||||
get() = CustomAnnotationTypeAttribute::class
|
||||
override val keepInInferredDeclarationType: Boolean
|
||||
get() = true
|
||||
|
||||
/**
|
||||
* Return an instance of the attribute that is not linked to any [containerSymbols].
|
||||
* It is required to avoid concurrent modification of those annotations from the linked
|
||||
* declaration and another call site (e.g., if a type was propagated to an anonymous function).
|
||||
*
|
||||
* See KT-60387 as an example of a possible concurrent problem.
|
||||
*/
|
||||
fun independentInstance(): CustomAnnotationTypeAttribute = if (containerSymbols.isEmpty()) {
|
||||
this
|
||||
} else {
|
||||
CustomAnnotationTypeAttribute(
|
||||
annotations = annotations.map {
|
||||
if (it is FirAnnotationCall) {
|
||||
buildAnnotationCallCopy(it) {}
|
||||
} else {
|
||||
buildAnnotationCopy(it) {}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val ConeAttributes.custom: CustomAnnotationTypeAttribute? by ConeAttributes.attributeAccessor<CustomAnnotationTypeAttribute>()
|
||||
|
||||
Reference in New Issue
Block a user