FIR/FE1.0: keep flexibility when approximating local types

This commit is contained in:
pyos
2022-09-12 18:08:35 +02:00
committed by teamcity
parent adcbc5ec99
commit be5c4a91a4
14 changed files with 222 additions and 28 deletions
@@ -16973,6 +16973,18 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
runTest("compiler/testData/diagnostics/tests/inference/substitutions/delegationAndInference.kt");
}
@Test
@TestMetadata("hideFlexibleLocalTypeInPublicPosition.kt")
public void testHideFlexibleLocalTypeInPublicPosition() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/substitutions/hideFlexibleLocalTypeInPublicPosition.kt");
}
@Test
@TestMetadata("hideFlexibleLocalTypeInPublicPosition_before.kt")
public void testHideFlexibleLocalTypeInPublicPosition_before() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/substitutions/hideFlexibleLocalTypeInPublicPosition_before.kt");
}
@Test
@TestMetadata("hideLocalTypeForReturnTypeOfSingleExpressionFunction.kt")
public void testHideLocalTypeForReturnTypeOfSingleExpressionFunction() throws Exception {
@@ -16985,6 +16997,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
runTest("compiler/testData/diagnostics/tests/inference/substitutions/hideNullableLocalTypeInPublicPosition.kt");
}
@Test
@TestMetadata("hideNullableLocalTypeInPublicPosition_before.kt")
public void testHideNullableLocalTypeInPublicPosition_before() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/substitutions/hideNullableLocalTypeInPublicPosition_before.kt");
}
@Test
@TestMetadata("kt32189returnTypeWithTypealiasSubtitution.kt")
public void testKt32189returnTypeWithTypealiasSubtitution() throws Exception {
@@ -16973,6 +16973,18 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
runTest("compiler/testData/diagnostics/tests/inference/substitutions/delegationAndInference.kt");
}
@Test
@TestMetadata("hideFlexibleLocalTypeInPublicPosition.kt")
public void testHideFlexibleLocalTypeInPublicPosition() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/substitutions/hideFlexibleLocalTypeInPublicPosition.kt");
}
@Test
@TestMetadata("hideFlexibleLocalTypeInPublicPosition_before.kt")
public void testHideFlexibleLocalTypeInPublicPosition_before() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/substitutions/hideFlexibleLocalTypeInPublicPosition_before.kt");
}
@Test
@TestMetadata("hideLocalTypeForReturnTypeOfSingleExpressionFunction.kt")
public void testHideLocalTypeForReturnTypeOfSingleExpressionFunction() throws Exception {
@@ -16985,6 +16997,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
runTest("compiler/testData/diagnostics/tests/inference/substitutions/hideNullableLocalTypeInPublicPosition.kt");
}
@Test
@TestMetadata("hideNullableLocalTypeInPublicPosition_before.kt")
public void testHideNullableLocalTypeInPublicPosition_before() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/substitutions/hideNullableLocalTypeInPublicPosition_before.kt");
}
@Test
@TestMetadata("kt32189returnTypeWithTypealiasSubtitution.kt")
public void testKt32189returnTypeWithTypealiasSubtitution() throws Exception {
@@ -12,7 +12,6 @@ import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.fakeElement
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.copyWithNewSourceKind
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.isEnumClass
import org.jetbrains.kotlin.fir.declarations.utils.isExpect
@@ -381,39 +380,50 @@ private fun FirTypeRef.hideLocalTypeIfNeeded(
session: FirSession,
isInlineFunction: Boolean = false
): FirTypeRef {
if (!shouldHideLocalType(containingCallableVisibility, isInlineFunction)) return this
if (this !is FirResolvedTypeRef || !shouldHideLocalType(containingCallableVisibility, isInlineFunction)) return this
return withReplacedConeType(type.approximateToOnlySupertype(session))
}
val coneType = coneTypeSafe<ConeClassLikeType>() ?: return this
val firClass = (coneType.lookupTag as? ConeClassLookupTagWithFixedSymbol)?.symbol?.fir
private fun ConeKotlinType.approximateToOnlySupertype(session: FirSession): ConeKotlinType? {
if (this is ConeFlexibleType) {
val lower = lowerBound.approximateToOnlySupertype(session)?.coneLowerBoundIfFlexible()
val upper = upperBound.approximateToOnlySupertype(session)?.coneUpperBoundIfFlexible()
if (lower == null && upper == null) {
return null
}
return coneFlexibleOrSimpleType(session.typeContext, lower ?: lowerBound, upper ?: upperBound)
}
if (this !is ConeClassLikeType) {
return null
}
val firClass = (lookupTag as? ConeClassLookupTagWithFixedSymbol)?.symbol?.fir
if (firClass !is FirAnonymousObject) {
// NB: local classes are acceptable here, but reported by EXPOSED_* checkers as errors
return this
return null
}
if (firClass.superTypeRefs.size > 1) {
// NB: don't approximate so members can be resolved. The error is reported by FirAmbiguousAnonymousTypeChecker.
return this
return null
}
val superType = firClass.superTypeRefs.single()
if (superType is FirResolvedTypeRef) {
val newKind = source?.kind
var result = superType
val resultTypeArguments = result.type.typeArguments
result = result.withReplacedConeType(result.type.withNullability(coneType.nullability, session.typeContext))
if (resultTypeArguments.isNotEmpty() && resultTypeArguments.size == coneType.typeArguments.size) {
val substitution = mutableMapOf<FirTypeParameterSymbol, ConeKotlinType>()
for (index in resultTypeArguments.indices) {
val key = resultTypeArguments[index]
val value = coneType.typeArguments[index]
val symbol = (key as? ConeTypeParameterType)?.lookupTag?.typeParameterSymbol ?: continue
substitution[symbol] = value.type!!
}
result = result.withReplacedConeType(ConeSubstitutorByMap(substitution, session).substituteOrSelf(result.type))
}
return if (newKind is KtFakeSourceElementKind) result.copyWithNewSourceKind(newKind) else result
if (superType !is FirResolvedTypeRef) {
return null
}
return this
val result = superType.type.withNullability(nullability, session.typeContext)
val resultTypeArguments = result.typeArguments
if (resultTypeArguments.isNotEmpty() && resultTypeArguments.size == typeArguments.size) {
val substitution = mutableMapOf<FirTypeParameterSymbol, ConeKotlinType>()
for (index in resultTypeArguments.indices) {
// TODO: this is not correct (should use firClass' arguments as keys); see comment in KT-51418
val key = resultTypeArguments[index]
val value = typeArguments[index]
val symbol = (key as? ConeTypeParameterType)?.lookupTag?.typeParameterSymbol ?: continue
substitution[symbol] = value.type!!
}
return ConeSubstitutorByMap(substitution, session).substituteOrSelf(result)
}
return result
}
fun shouldHideLocalType(containingCallableVisibility: Visibility?, isInlineFunction: Boolean): Boolean {