FIR: keep nullability when approximating local types
^KT-30054 Open
This commit is contained in:
+6
@@ -16979,6 +16979,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
||||
runTest("compiler/testData/diagnostics/tests/inference/substitutions/hideLocalTypeForReturnTypeOfSingleExpressionFunction.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("hideNullableLocalTypeInPublicPosition.kt")
|
||||
public void testHideNullableLocalTypeInPublicPosition() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/substitutions/hideNullableLocalTypeInPublicPosition.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt32189returnTypeWithTypealiasSubtitution.kt")
|
||||
public void testKt32189returnTypeWithTypealiasSubtitution() throws Exception {
|
||||
|
||||
+6
@@ -16979,6 +16979,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
|
||||
runTest("compiler/testData/diagnostics/tests/inference/substitutions/hideLocalTypeForReturnTypeOfSingleExpressionFunction.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("hideNullableLocalTypeInPublicPosition.kt")
|
||||
public void testHideNullableLocalTypeInPublicPosition() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/substitutions/hideNullableLocalTypeInPublicPosition.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt32189returnTypeWithTypealiasSubtitution.kt")
|
||||
public void testKt32189returnTypeWithTypealiasSubtitution() throws Exception {
|
||||
|
||||
@@ -383,11 +383,8 @@ private fun FirTypeRef.hideLocalTypeIfNeeded(
|
||||
): FirTypeRef {
|
||||
if (!shouldHideLocalType(containingCallableVisibility, isInlineFunction)) return this
|
||||
|
||||
val firClass =
|
||||
(((this as? FirResolvedTypeRef)
|
||||
?.type as? ConeClassLikeType)
|
||||
?.lookupTag as? ConeClassLookupTagWithFixedSymbol)
|
||||
?.symbol?.fir
|
||||
val coneType = coneTypeSafe<ConeClassLikeType>() ?: return this
|
||||
val firClass = (coneType.lookupTag as? ConeClassLookupTagWithFixedSymbol)?.symbol?.fir
|
||||
if (firClass !is FirAnonymousObject) {
|
||||
// NB: local classes are acceptable here, but reported by EXPOSED_* checkers as errors
|
||||
return this
|
||||
@@ -402,6 +399,7 @@ private fun FirTypeRef.hideLocalTypeIfNeeded(
|
||||
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) {
|
||||
@@ -410,9 +408,7 @@ private fun FirTypeRef.hideLocalTypeIfNeeded(
|
||||
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)
|
||||
result = result.withReplacedConeType(ConeSubstitutorByMap(substitution, session).substituteOrSelf(result.type))
|
||||
}
|
||||
|
||||
return if (newKind is KtFakeSourceElementKind) result.copyWithNewSourceKind(newKind) else result
|
||||
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
// ISSUE: KT-30054
|
||||
interface I {
|
||||
fun foo(): String
|
||||
}
|
||||
|
||||
fun bar(condition: Boolean) /*: I? */ =
|
||||
if (condition)
|
||||
object : I {
|
||||
override fun foo() = "should check for null first"
|
||||
fun baz() = "invisible"
|
||||
}
|
||||
else null
|
||||
|
||||
fun main() {
|
||||
bar(false).<!UNRESOLVED_REFERENCE!>baz<!>()
|
||||
bar(false)<!UNSAFE_CALL!>.<!>foo()
|
||||
bar(false)?.foo()
|
||||
}
|
||||
compiler/testData/diagnostics/tests/inference/substitutions/hideNullableLocalTypeInPublicPosition.kt
Vendored
+18
@@ -0,0 +1,18 @@
|
||||
// ISSUE: KT-30054
|
||||
interface I {
|
||||
fun foo(): String
|
||||
}
|
||||
|
||||
fun bar(condition: Boolean) /*: I? */ =
|
||||
if (condition)
|
||||
object : I {
|
||||
override fun foo() = "should check for null first"
|
||||
fun baz() = "invisible"
|
||||
}
|
||||
else null
|
||||
|
||||
fun main() {
|
||||
bar(false).<!UNRESOLVED_REFERENCE!>baz<!>()
|
||||
bar(false).foo()
|
||||
bar(false)<!UNNECESSARY_SAFE_CALL!>?.<!>foo()
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
package
|
||||
|
||||
public fun bar(/*0*/ condition: kotlin.Boolean): I
|
||||
public fun main(): kotlin.Unit
|
||||
|
||||
public interface I {
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public abstract fun foo(): kotlin.String
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
Generated
+6
@@ -16985,6 +16985,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/substitutions/hideLocalTypeForReturnTypeOfSingleExpressionFunction.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("hideNullableLocalTypeInPublicPosition.kt")
|
||||
public void testHideNullableLocalTypeInPublicPosition() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/substitutions/hideNullableLocalTypeInPublicPosition.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt32189returnTypeWithTypealiasSubtitution.kt")
|
||||
public void testKt32189returnTypeWithTypealiasSubtitution() throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user