diff --git a/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/FirMetadataSerializer.kt b/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/FirMetadataSerializer.kt index 627f5acec25..3de2ce2d47a 100644 --- a/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/FirMetadataSerializer.kt +++ b/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/FirMetadataSerializer.kt @@ -17,7 +17,6 @@ import org.jetbrains.kotlin.fir.declarations.FirTypeParameter import org.jetbrains.kotlin.fir.declarations.builder.* import org.jetbrains.kotlin.fir.diagnostics.ConeIntermediateDiagnostic import org.jetbrains.kotlin.fir.typeContext -import org.jetbrains.kotlin.fir.scopes.impl.withReplacedConeType import org.jetbrains.kotlin.fir.serialization.FirElementSerializer import org.jetbrains.kotlin.fir.symbols.impl.FirAnonymousFunctionSymbol import org.jetbrains.kotlin.fir.types.* diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt index 50ffc4a98b4..3789546ed04 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt @@ -24,7 +24,6 @@ import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents import org.jetbrains.kotlin.fir.resolve.providers.* import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType import org.jetbrains.kotlin.fir.resolve.transformers.ensureResolved -import org.jetbrains.kotlin.fir.scopes.impl.withReplacedConeType import org.jetbrains.kotlin.fir.symbols.* import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.types.* diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConstructorProcessing.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConstructorProcessing.kt index d603076a2ac..3975c09a470 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConstructorProcessing.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConstructorProcessing.kt @@ -15,13 +15,9 @@ import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.fir.scopes.impl.FirClassSubstitutionScope -import org.jetbrains.kotlin.fir.scopes.impl.withReplacedConeType import org.jetbrains.kotlin.fir.scopes.scope import org.jetbrains.kotlin.fir.symbols.impl.* -import org.jetbrains.kotlin.fir.types.ConeClassLikeType -import org.jetbrains.kotlin.fir.types.ConeKotlinType -import org.jetbrains.kotlin.fir.types.coneType -import org.jetbrains.kotlin.fir.types.coneTypeUnsafe +import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.name.Name private operator fun Pair?.component1() = this?.first diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirCallCompletionResultsWriterTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirCallCompletionResultsWriterTransformer.kt index e1ca20624ec..e05e7e2df44 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirCallCompletionResultsWriterTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirCallCompletionResultsWriterTransformer.kt @@ -28,7 +28,6 @@ import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.remapArguments import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.writeResultType import org.jetbrains.kotlin.fir.scopes.impl.FirIntegerOperatorCall -import org.jetbrains.kotlin.fir.scopes.impl.withReplacedConeType import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/TransformUtils.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/TransformUtils.kt index 5cdd8ca27e9..ce127ba5881 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/TransformUtils.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/TransformUtils.kt @@ -11,7 +11,6 @@ import org.jetbrains.kotlin.fir.declarations.FirTypedDeclaration import org.jetbrains.kotlin.fir.declarations.FirValueParameter import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.references.* -import org.jetbrains.kotlin.fir.scopes.impl.withReplacedConeType import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.visitors.* diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveUtils.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveUtils.kt index b6350a014ee..76001229918 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveUtils.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveUtils.kt @@ -14,12 +14,8 @@ import org.jetbrains.kotlin.fir.expressions.FirBlock import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirReturnExpression import org.jetbrains.kotlin.fir.expressions.builder.buildVarargArgumentsExpression -import org.jetbrains.kotlin.fir.scopes.impl.withReplacedConeType import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol -import org.jetbrains.kotlin.fir.types.ConeKotlinType -import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef -import org.jetbrains.kotlin.fir.types.FirTypeRef -import org.jetbrains.kotlin.fir.types.arrayElementType +import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef import kotlin.math.min 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 13c4ffb76fe..ce5e9ad7a7c 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 @@ -6,11 +6,6 @@ package org.jetbrains.kotlin.fir.resolve.transformers.body.resolve import org.jetbrains.kotlin.descriptors.ClassKind -import org.jetbrains.kotlin.descriptors.Visibilities.Internal -import org.jetbrains.kotlin.descriptors.Visibilities.Private -import org.jetbrains.kotlin.descriptors.Visibilities.Protected -import org.jetbrains.kotlin.descriptors.Visibilities.Public -import org.jetbrains.kotlin.descriptors.Visibility import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.builder.buildValueParameter @@ -34,9 +29,7 @@ import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor import org.jetbrains.kotlin.fir.resolve.transformers.* import org.jetbrains.kotlin.fir.scopes.impl.FirLocalScope import org.jetbrains.kotlin.fir.scopes.impl.FirMemberTypeParameterScope -import org.jetbrains.kotlin.fir.scopes.impl.withReplacedConeType import org.jetbrains.kotlin.fir.symbols.constructStarProjectedType -import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLookupTagWithFixedSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef @@ -44,7 +37,6 @@ import org.jetbrains.kotlin.fir.types.builder.buildImplicitTypeRef import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef import org.jetbrains.kotlin.fir.visitors.* import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.types.TypeApproximatorConfiguration import org.jetbrains.kotlin.utils.addToStdlib.safeAs open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer) : FirPartialBodyResolveTransformer(transformer) { @@ -511,7 +503,9 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor result.transformReturnTypeRef( transformer, withExpectedType( - body.resultType.approximateTypeIfNeeded(simpleFunction?.visibility, simpleFunction?.isInline == true) + body.resultType.approximatedIfNeededOrSelf( + inferenceComponents.approximator, simpleFunction?.visibility, simpleFunction?.isInline == true + ) ) ) } else { @@ -923,7 +917,9 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor } variable.transformReturnTypeRef( transformer, - withExpectedType(expectedType.approximateTypeIfNeeded((variable as? FirProperty)?.visibility)) + withExpectedType( + expectedType.approximatedIfNeededOrSelf(inferenceComponents.approximator, (variable as? FirProperty)?.visibility) + ) ) } variable.getter != null && variable.getter !is FirDefaultPropertyAccessor -> { @@ -945,7 +941,9 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor } variable.transformReturnTypeRef( transformer, - withExpectedType(expectedType?.approximateTypeIfNeeded((variable as? FirProperty)?.visibility)) + withExpectedType( + expectedType?.approximatedIfNeededOrSelf(inferenceComponents.approximator, (variable as? FirProperty)?.visibility) + ) ) } else -> { @@ -968,87 +966,6 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor } } - private fun ConeKotlinType.requiresApproximationInPublicPosition(): Boolean { - return when (this) { - is ConeIntegerLiteralType, - is ConeCapturedType, - is ConeDefinitelyNotNullType, - is ConeIntersectionType -> true - is ConeClassLikeType -> typeArguments.any { - it is ConeKotlinTypeProjection && it.type.requiresApproximationInPublicPosition() - } - else -> false - } - } - - private fun FirTypeRef.approximateTypeIfNeeded( - containingCallableVisibility: Visibility?, - isInlineFunction: Boolean = false - ): FirTypeRef { - val approximatedType = if (this is FirResolvedTypeRef && - (containingCallableVisibility == Public || containingCallableVisibility == Protected) - ) { - if (type.requiresApproximationInPublicPosition()) { - this.withReplacedConeType( - inferenceComponents.approximator.approximateToSuperType( - this.type, TypeApproximatorConfiguration.PublicDeclaration - ) as? ConeKotlinType - ) - } else { - this - } - } else { - this - } - return approximatedType.hideLocalTypeIfNeeded(containingCallableVisibility, isInlineFunction) - } - - /* - * Suppose a function without an explicit return type just returns an anonymous object: - * - * fun foo(...) = object : ObjectSuperType { - * override fun ... - * } - * - * Without unwrapping, the return type ended up with that anonymous object (), while the resolved super type, which - * acts like an implementing interface, is a better fit. In fact, exposing an anonymous object types is prohibited for certain cases, - * e.g., KT-33917. We can also apply this to any local types. - */ - private fun FirTypeRef.hideLocalTypeIfNeeded( - containingCallableVisibility: Visibility?, - isInlineFunction: Boolean = false - ): FirTypeRef { - if (containingCallableVisibility == null) { - return this - } - // Approximate types for non-private (all but package private or private) members. - // Also private inline functions, as per KT-33917. - if (containingCallableVisibility == Public || - containingCallableVisibility == Protected || - containingCallableVisibility == Internal || - (containingCallableVisibility == Private && isInlineFunction) - ) { - val firClass = - (((this as? FirResolvedTypeRef) - ?.type as? ConeClassLikeType) - ?.lookupTag as? ConeClassLookupTagWithFixedSymbol) - ?.symbol?.fir - if (firClass?.classId?.isLocal != true) { - return this - } - if (firClass.superTypeRefs.size > 1) { - return buildErrorTypeRef { - diagnostic = ConeSimpleDiagnostic("Cannot hide local type ${firClass.render()}") - } - } - val superType = firClass.superTypeRefs.single() - if (superType is FirResolvedTypeRef && !superType.isAny) { - return superType - } - } - return this - } - private object ImplicitToErrorTypeTransformer : FirTransformer() { override fun transformElement(element: E, data: Nothing?): CompositeTransformResult { return element.compose() diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt index 39ec1d85647..89f73b4f55c 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt @@ -27,7 +27,6 @@ import org.jetbrains.kotlin.fir.resolve.inference.FirStubInferenceSession import org.jetbrains.kotlin.fir.resolve.transformers.InvocationKindTransformer import org.jetbrains.kotlin.fir.resolve.transformers.StoreReceiver import org.jetbrains.kotlin.fir.resolve.transformers.firClassLike -import org.jetbrains.kotlin.fir.scopes.impl.withReplacedConeType import org.jetbrains.kotlin.fir.symbols.StandardClassIds import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol import org.jetbrains.kotlin.fir.types.* diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirClassSubstitutionScope.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirClassSubstitutionScope.kt index c61a16a0014..a6a768ad263 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirClassSubstitutionScope.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirClassSubstitutionScope.kt @@ -626,33 +626,3 @@ class FirClassSubstitutionScope( return useSiteMemberScope.getClassifierNames() } } - -// Unlike other cases, return types may be implicit, i.e. unresolved -// But in that cases newType should also be `null` -fun FirTypeRef.withReplacedReturnType(newType: ConeKotlinType?): FirTypeRef { - require(this is FirResolvedTypeRef || newType == null) - if (newType == null) return this - - return buildResolvedTypeRef { - source = this@withReplacedReturnType.source - type = newType - annotations += this@withReplacedReturnType.annotations - } -} - -fun FirTypeRef.withReplacedConeType( - newType: ConeKotlinType?, - firFakeSourceElementKind: FirFakeSourceElementKind? = null -): FirResolvedTypeRef { - require(this is FirResolvedTypeRef) - if (newType == null) return this - - return buildResolvedTypeRef { - source = if (firFakeSourceElementKind != null) - this@withReplacedConeType.source?.fakeElement(firFakeSourceElementKind) - else - this@withReplacedConeType.source - type = newType - annotations += this@withReplacedConeType.annotations - } -} diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/TypeUtils.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/TypeUtils.kt index 14ff7d5ee3a..a5006fdf445 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/TypeUtils.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/TypeUtils.kt @@ -5,9 +5,18 @@ package org.jetbrains.kotlin.fir.types +import org.jetbrains.kotlin.descriptors.Visibilities +import org.jetbrains.kotlin.descriptors.Visibility +import org.jetbrains.kotlin.fir.FirFakeSourceElementKind import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.declarations.classId +import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic +import org.jetbrains.kotlin.fir.fakeElement +import org.jetbrains.kotlin.fir.render import org.jetbrains.kotlin.fir.resolve.fullyExpandedType -import org.jetbrains.kotlin.fir.scopes.impl.withReplacedConeType +import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLookupTagWithFixedSymbol +import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef +import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl import org.jetbrains.kotlin.resolve.calls.NewCommonSuperTypeCalculator @@ -174,6 +183,36 @@ fun FirTypeRef.isUnsafeVarianceType(session: FirSession): Boolean { return coneTypeSafe()?.isUnsafeVarianceType(session) == true } +// Unlike other cases, return types may be implicit, i.e. unresolved +// But in that cases newType should also be `null` +fun FirTypeRef.withReplacedReturnType(newType: ConeKotlinType?): FirTypeRef { + require(this is FirResolvedTypeRef || newType == null) + if (newType == null) return this + + return buildResolvedTypeRef { + source = this@withReplacedReturnType.source + type = newType + annotations += this@withReplacedReturnType.annotations + } +} + +fun FirTypeRef.withReplacedConeType( + newType: ConeKotlinType?, + firFakeSourceElementKind: FirFakeSourceElementKind? = null +): FirResolvedTypeRef { + require(this is FirResolvedTypeRef) + if (newType == null) return this + + return buildResolvedTypeRef { + source = if (firFakeSourceElementKind != null) + this@withReplacedConeType.source?.fakeElement(firFakeSourceElementKind) + else + this@withReplacedConeType.source + type = newType + annotations += this@withReplacedConeType.annotations + } +} + fun FirTypeRef.approximated( typeApproximator: AbstractTypeApproximator, toSuper: Boolean, @@ -186,3 +225,77 @@ fun FirTypeRef.approximated( return withReplacedConeType(approximatedType as? ConeKotlinType) } +fun FirTypeRef.approximatedIfNeededOrSelf( + approximator: AbstractTypeApproximator, + containingCallableVisibility: Visibility?, + isInlineFunction: Boolean = false +): FirTypeRef { + val approximatedType = if (this is FirResolvedTypeRef && + (containingCallableVisibility == Visibilities.Public || containingCallableVisibility == Visibilities.Protected) + ) { + if (type.requiresApproximationInPublicPosition()) this.approximated(approximator, toSuper = true) else this + } else { + this + } + return approximatedType.hideLocalTypeIfNeeded(containingCallableVisibility, isInlineFunction) +} + +private fun ConeKotlinType.requiresApproximationInPublicPosition(): Boolean { + return when (this) { + is ConeIntegerLiteralType, + is ConeCapturedType, + is ConeDefinitelyNotNullType, + is ConeIntersectionType -> true + is ConeClassLikeType -> typeArguments.any { + it is ConeKotlinTypeProjection && it.type.requiresApproximationInPublicPosition() + } + else -> false + } +} + +/* + * Suppose a function without an explicit return type just returns an anonymous object: + * + * fun foo(...) = object : ObjectSuperType { + * override fun ... + * } + * + * Without unwrapping, the return type ended up with that anonymous object (), while the resolved super type, which + * acts like an implementing interface, is a better fit. In fact, exposing an anonymous object types is prohibited for certain cases, + * e.g., KT-33917. We can also apply this to any local types. + */ +private fun FirTypeRef.hideLocalTypeIfNeeded( + containingCallableVisibility: Visibility?, + isInlineFunction: Boolean = false +): FirTypeRef { + if (containingCallableVisibility == null) { + return this + } + // Approximate types for non-private (all but package private or private) members. + // Also private inline functions, as per KT-33917. + if (containingCallableVisibility == Visibilities.Public || + containingCallableVisibility == Visibilities.Protected || + containingCallableVisibility == Visibilities.Internal || + (containingCallableVisibility == Visibilities.Private && isInlineFunction) + ) { + val firClass = + (((this as? FirResolvedTypeRef) + ?.type as? ConeClassLikeType) + ?.lookupTag as? ConeClassLookupTagWithFixedSymbol) + ?.symbol?.fir + if (firClass?.classId?.isLocal != true) { + return this + } + if (firClass.superTypeRefs.size > 1) { + return buildErrorTypeRef { + diagnostic = ConeSimpleDiagnostic("Cannot hide local type ${firClass.render()}") + } + } + val superType = firClass.superTypeRefs.single() + if (superType is FirResolvedTypeRef && !superType.isAny) { + return superType + } + } + return this +} +