[FIR] Hide local type for return type of single expression function ^KT-51418 Fixed
This commit is contained in:
+6
@@ -16287,6 +16287,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag
|
||||
runTest("compiler/testData/diagnostics/tests/inference/substitutions/delegationAndInference.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("hideLocalTypeForReturnTypeOfSingleExpressionFunction.kt")
|
||||
public void testHideLocalTypeForReturnTypeOfSingleExpressionFunction() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/substitutions/hideLocalTypeForReturnTypeOfSingleExpressionFunction.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt32189returnTypeWithTypealiasSubtitution.kt")
|
||||
public void testKt32189returnTypeWithTypealiasSubtitution() throws Exception {
|
||||
|
||||
+6
@@ -16287,6 +16287,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
||||
runTest("compiler/testData/diagnostics/tests/inference/substitutions/delegationAndInference.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("hideLocalTypeForReturnTypeOfSingleExpressionFunction.kt")
|
||||
public void testHideLocalTypeForReturnTypeOfSingleExpressionFunction() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/substitutions/hideLocalTypeForReturnTypeOfSingleExpressionFunction.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt32189returnTypeWithTypealiasSubtitution.kt")
|
||||
public void testKt32189returnTypeWithTypealiasSubtitution() throws Exception {
|
||||
|
||||
+6
@@ -16287,6 +16287,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
|
||||
runTest("compiler/testData/diagnostics/tests/inference/substitutions/delegationAndInference.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("hideLocalTypeForReturnTypeOfSingleExpressionFunction.kt")
|
||||
public void testHideLocalTypeForReturnTypeOfSingleExpressionFunction() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/substitutions/hideLocalTypeForReturnTypeOfSingleExpressionFunction.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt32189returnTypeWithTypealiasSubtitution.kt")
|
||||
public void testKt32189returnTypeWithTypealiasSubtitution() throws Exception {
|
||||
|
||||
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.fir.copyWithNewSourceKind
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.visibility
|
||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutorByMap
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||
import org.jetbrains.kotlin.fir.resolvedTypeFromPrototype
|
||||
@@ -22,6 +23,7 @@ import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLookupTagWithFixedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
||||
@@ -318,13 +320,14 @@ fun FirTypeRef.approximated(
|
||||
fun FirTypeRef.approximatedIfNeededOrSelf(
|
||||
approximator: ConeTypeApproximator,
|
||||
containingCallableVisibility: Visibility?,
|
||||
isInlineFunction: Boolean = false,
|
||||
session: FirSession,
|
||||
isInlineFunction: Boolean = false
|
||||
): FirTypeRef {
|
||||
val approximated = if (containingCallableVisibility == Visibilities.Public || containingCallableVisibility == Visibilities.Protected)
|
||||
approximatedForPublicPosition(approximator)
|
||||
else
|
||||
this
|
||||
return approximated.hideLocalTypeIfNeeded(containingCallableVisibility, isInlineFunction).withoutEnhancedNullability()
|
||||
return approximated.hideLocalTypeIfNeeded(containingCallableVisibility, session, isInlineFunction).withoutEnhancedNullability()
|
||||
}
|
||||
|
||||
fun FirTypeRef.approximatedForPublicPosition(approximator: ConeTypeApproximator): FirTypeRef =
|
||||
@@ -350,9 +353,11 @@ private fun ConeKotlinType.requiresApproximationInPublicPosition(): Boolean = co
|
||||
*/
|
||||
private fun FirTypeRef.hideLocalTypeIfNeeded(
|
||||
containingCallableVisibility: Visibility?,
|
||||
session: FirSession,
|
||||
isInlineFunction: Boolean = false
|
||||
): FirTypeRef {
|
||||
if (!shouldHideLocalType(containingCallableVisibility, isInlineFunction)) return this
|
||||
|
||||
val firClass =
|
||||
(((this as? FirResolvedTypeRef)
|
||||
?.type as? ConeClassLikeType)
|
||||
@@ -369,7 +374,23 @@ private fun FirTypeRef.hideLocalTypeIfNeeded(
|
||||
val superType = firClass.superTypeRefs.single()
|
||||
if (superType is FirResolvedTypeRef) {
|
||||
val newKind = source?.kind
|
||||
return if (newKind is KtFakeSourceElementKind) superType.copyWithNewSourceKind(newKind) else superType
|
||||
var result = superType
|
||||
val resultTypeArguments = result.type.typeArguments
|
||||
|
||||
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!!
|
||||
}
|
||||
|
||||
val substituted = ConeSubstitutorByMap(substitution, session).substituteOrSelf(result.type)
|
||||
result = substituted.toFirResolvedTypeRef(superType.source, superType.delegatedTypeRef)
|
||||
}
|
||||
|
||||
return if (newKind is KtFakeSourceElementKind) result.copyWithNewSourceKind(newKind) else result
|
||||
}
|
||||
return this
|
||||
}
|
||||
@@ -383,7 +404,7 @@ fun shouldHideLocalType(containingCallableVisibility: Visibility?, isInlineFunct
|
||||
return containingCallableVisibility == Visibilities.Public ||
|
||||
containingCallableVisibility == Visibilities.Protected ||
|
||||
containingCallableVisibility == Visibilities.Internal ||
|
||||
(containingCallableVisibility == Visibilities.Private && isInlineFunction)
|
||||
containingCallableVisibility == Visibilities.Private && isInlineFunction
|
||||
}
|
||||
|
||||
fun FirDeclaration.visibilityForApproximation(container: FirDeclaration?): Visibility {
|
||||
|
||||
+1
-1
@@ -952,7 +952,7 @@ internal class FirDeclarationCompletionResultsWriter(
|
||||
typeRef.resolvedTypeFromPrototype(it)
|
||||
} ?: typeRef
|
||||
if (data is ApproximationData.ApproximateByStatus) {
|
||||
return result.approximatedIfNeededOrSelf(typeApproximator, data.visibility, data.isInline)
|
||||
return result.approximatedIfNeededOrSelf(typeApproximator, data.visibility, this.typeContext.session, data.isInline)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
+21
-20
@@ -344,7 +344,11 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
|
||||
typeVariableTypeToStubType, session.typeContext, approximateIntegerLiterals = true
|
||||
)
|
||||
|
||||
val stubTypeSubstituted = substitutor.substituteOrSelf(provideDelegateCandidate.substitutor.substituteOrSelf(components.typeFromCallee(provideDelegateCall).type))
|
||||
val stubTypeSubstituted = substitutor.substituteOrSelf(
|
||||
provideDelegateCandidate.substitutor.substituteOrSelf(
|
||||
components.typeFromCallee(provideDelegateCall).type
|
||||
)
|
||||
)
|
||||
|
||||
provideDelegateCall.replaceTypeRef(provideDelegateCall.typeRef.resolvedTypeFromPrototype(stubTypeSubstituted))
|
||||
return provideDelegateCall
|
||||
@@ -624,14 +628,15 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
|
||||
if (result.returnTypeRef is FirImplicitTypeRef) {
|
||||
val simpleFunction = function as? FirSimpleFunction
|
||||
val returnExpression = (body?.statements?.single() as? FirReturnExpression)?.result
|
||||
if (returnExpression != null && returnExpression.typeRef is FirResolvedTypeRef) {
|
||||
if (returnExpression?.typeRef is FirResolvedTypeRef) {
|
||||
result.transformReturnTypeRef(
|
||||
transformer,
|
||||
withExpectedType(
|
||||
returnExpression.resultType.approximatedIfNeededOrSelf(
|
||||
session.typeApproximator,
|
||||
simpleFunction?.visibilityForApproximation(),
|
||||
simpleFunction?.isInline == true
|
||||
session,
|
||||
isInlineFunction = simpleFunction?.isInline == true
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -1009,6 +1014,7 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
|
||||
expectedType.approximatedIfNeededOrSelf(
|
||||
session.typeApproximator,
|
||||
backingField.visibilityForApproximation(),
|
||||
session
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -1025,28 +1031,23 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
|
||||
variable.getter != null && variable.getter !is FirDefaultPropertyAccessor -> variable.getter?.returnTypeRef
|
||||
else -> null
|
||||
}
|
||||
if (resultType != null) {
|
||||
val expectedType = resultType.toExpectedTypeRef()
|
||||
variable.transformReturnTypeRef(
|
||||
transformer,
|
||||
withExpectedType(
|
||||
|
||||
variable.transformReturnTypeRef(
|
||||
transformer,
|
||||
withExpectedType(
|
||||
resultType?.let {
|
||||
val expectedType = it.toExpectedTypeRef()
|
||||
expectedType.approximatedIfNeededOrSelf(
|
||||
session.typeApproximator,
|
||||
variable.visibilityForApproximation(),
|
||||
session
|
||||
)
|
||||
)
|
||||
} ?: buildErrorTypeRef {
|
||||
diagnostic = ConeLocalVariableNoTypeOrInitializer(variable)
|
||||
source = variable.source
|
||||
}
|
||||
)
|
||||
} else {
|
||||
variable.transformReturnTypeRef(
|
||||
transformer,
|
||||
withExpectedType(
|
||||
buildErrorTypeRef {
|
||||
diagnostic = ConeLocalVariableNoTypeOrInitializer(variable)
|
||||
source = variable.source
|
||||
},
|
||||
)
|
||||
)
|
||||
}
|
||||
)
|
||||
if (variable.getter?.returnTypeRef is FirImplicitTypeRef) {
|
||||
variable.getter?.transformReturnTypeRef(transformer, withExpectedType(variable.returnTypeRef))
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
|
||||
abstract class A<T> {
|
||||
fun print() = "OK"
|
||||
}
|
||||
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
// FIR_IDENTICAL
|
||||
// ISSUE: KT-51418
|
||||
|
||||
abstract class A<T>
|
||||
private fun fPrivate() = test("private")
|
||||
fun fPublic() = test("public")
|
||||
|
||||
private fun <T> test(t: T) = object : A<T>() {
|
||||
fun bar(): T = t
|
||||
}
|
||||
|
||||
fun main() {
|
||||
fPrivate().bar()
|
||||
fPublic().<!UNRESOLVED_REFERENCE!>bar<!>()
|
||||
test(1).bar()
|
||||
}
|
||||
|
||||
class FieldTest {
|
||||
var result = ""
|
||||
|
||||
private val test = object {
|
||||
fun bar() = object {
|
||||
fun qux() = object {
|
||||
}.also { result += "b" }
|
||||
}.also { result += "a" }
|
||||
}.also { result += "!" }
|
||||
|
||||
private val ttt = test.bar()
|
||||
private val qqq = ttt.qux()
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
package
|
||||
|
||||
private fun fPrivate(): test.`<no name provided>`<kotlin.String>
|
||||
public fun fPublic(): A<kotlin.String>
|
||||
public fun main(): kotlin.Unit
|
||||
private fun </*0*/ T> test(/*0*/ t: T): test.`<no name provided>`<T>
|
||||
|
||||
public abstract class A</*0*/ T> {
|
||||
public constructor A</*0*/ T>()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class FieldTest {
|
||||
public constructor FieldTest()
|
||||
private final val qqq: FieldTest.test.`<no name provided>`.bar.`<no name provided>`.qux.`<no name provided>`
|
||||
public final var result: kotlin.String
|
||||
private final val test: FieldTest.test.`<no name provided>`
|
||||
private final val ttt: FieldTest.test.`<no name provided>`.bar.`<no name provided>`
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
Generated
+6
@@ -16293,6 +16293,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/substitutions/delegationAndInference.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("hideLocalTypeForReturnTypeOfSingleExpressionFunction.kt")
|
||||
public void testHideLocalTypeForReturnTypeOfSingleExpressionFunction() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/substitutions/hideLocalTypeForReturnTypeOfSingleExpressionFunction.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt32189returnTypeWithTypealiasSubtitution.kt")
|
||||
public void testKt32189returnTypeWithTypealiasSubtitution() throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user