[FIR] Don't smartcast variables to invisible types

#KT-44802 Fixed
This commit is contained in:
Dmitriy Novozhilov
2021-02-18 11:19:08 +03:00
parent 026efca49f
commit 1c0d862e40
24 changed files with 521 additions and 17 deletions
@@ -2885,6 +2885,11 @@ public class LazyBodyIsNotTouchedTilContractsPhaseTestGenerated extends Abstract
runTest("compiler/fir/analysis-tests/testData/resolve/smartcasts/smartcastToNothing.kt");
}
@TestMetadata("smartcastToTypeParameter.kt")
public void testSmartcastToTypeParameter() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/smartcasts/smartcastToTypeParameter.kt");
}
@TestMetadata("compiler/fir/analysis-tests/testData/resolve/smartcasts/booleans")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -0,0 +1,43 @@
FILE: smartcastToTypeParameter.kt
public abstract interface FirTypeScope : R|kotlin/Any| {
}
public abstract interface AbstractFirBasedSymbol<E : R|FirSymbolOwner<E>|, R|FirDeclaration|> : R|kotlin/Any| {
public abstract val fir: R|E|
public get(): R|E|
}
public abstract interface FirCallableSymbol<D : R|FirCallableDeclaration<D>|> : R|AbstractFirBasedSymbol<D>| {
}
public abstract interface FirElement : R|kotlin/Any| {
}
public abstract interface FirSymbolOwner<E : R|FirSymbolOwner<E>|, R|FirDeclaration|> : R|FirElement| {
public abstract val symbol: R|AbstractFirBasedSymbol<E>|
public get(): R|AbstractFirBasedSymbol<E>|
}
public abstract interface FirDeclaration : R|FirElement| {
}
public abstract interface FirCallableDeclaration<F : R|FirCallableDeclaration<F>|> : R|FirDeclaration|, R|FirSymbolOwner<F>| {
}
public abstract interface FirCallableMemberDeclaration<F : R|FirCallableMemberDeclaration<F>|> : R|FirCallableDeclaration<F>| {
}
private final inline fun <reified S : R|FirCallableSymbol<*>|> computeBaseSymbols(symbol: R|S|, basedSymbol: R|S|, directOverridden: R|FirTypeScope.(S) -> kotlin/collections/List<S>|): R|kotlin/Unit| {
}
public final fun R|FirCallableSymbol<*>|.dispatchReceiverClassOrNull(): R|kotlin/Boolean?| {
^dispatchReceiverClassOrNull Boolean(true)
}
private final inline fun <reified D : R|FirCallableMemberDeclaration<D>|, reified S : R|FirCallableSymbol<D>|> createFakeOverriddenIfNeeded(originalSymbol: R|FirCallableSymbol<*>|, basedSymbol: R|S|, computeDirectOverridden: R|FirTypeScope.(S) -> kotlin/collections/List<S>|, someCondition: R|kotlin/Boolean|): R|kotlin/Unit| {
when () {
(R|<local>/originalSymbol| !is R|S|) -> {
^createFakeOverriddenIfNeeded Unit
}
}
when () {
==(R|<local>/originalSymbol|.R|/dispatchReceiverClassOrNull|(), Boolean(true)) && R|<local>/someCondition| -> {
^createFakeOverriddenIfNeeded Unit
}
}
R|/computeBaseSymbols|<R|S|>(R|<local>/originalSymbol|, R|<local>/basedSymbol|, R|<local>/computeDirectOverridden|)
}
@@ -0,0 +1,34 @@
interface FirTypeScope
interface AbstractFirBasedSymbol<E> where E : FirSymbolOwner<E>, E : FirDeclaration {
val fir: E
}
interface FirCallableSymbol<D : FirCallableDeclaration<D>> : AbstractFirBasedSymbol<D>
interface FirElement
interface FirSymbolOwner<E> : FirElement where E : FirSymbolOwner<E>, E : FirDeclaration {
val symbol: AbstractFirBasedSymbol<E>
}
interface FirDeclaration : FirElement
interface FirCallableDeclaration<F : FirCallableDeclaration<F>> : FirDeclaration, FirSymbolOwner<F>
interface FirCallableMemberDeclaration<F : FirCallableMemberDeclaration<F>> : FirCallableDeclaration<F>
private inline fun <reified S : FirCallableSymbol<*>> computeBaseSymbols(
symbol: S,
basedSymbol: S,
directOverridden: FirTypeScope.(S) -> List<S>
) {}
fun FirCallableSymbol<*>.dispatchReceiverClassOrNull(): Boolean? = true
private inline fun <reified D : FirCallableMemberDeclaration<D>, reified S : FirCallableSymbol<D>> createFakeOverriddenIfNeeded(
originalSymbol: FirCallableSymbol<*>,
basedSymbol: S,
computeDirectOverridden: FirTypeScope.(S) -> List<S>,
someCondition: Boolean
) {
if (originalSymbol !is S) return
if (originalSymbol.dispatchReceiverClassOrNull() == true && someCondition) return
computeBaseSymbols(originalSymbol, basedSymbol, computeDirectOverridden)
}
@@ -3263,6 +3263,12 @@ public class FirDiagnosticTestGenerated extends AbstractFirDiagnosticTest {
runTest("compiler/fir/analysis-tests/testData/resolve/smartcasts/smartcastToNothing.kt");
}
@Test
@TestMetadata("smartcastToTypeParameter.kt")
public void testSmartcastToTypeParameter() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/smartcasts/smartcastToTypeParameter.kt");
}
@Nested
@TestMetadata("compiler/fir/analysis-tests/testData/resolve/smartcasts/booleans")
@TestDataPath("$PROJECT_ROOT")
@@ -3300,6 +3300,12 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
runTest("compiler/fir/analysis-tests/testData/resolve/smartcasts/smartcastToNothing.kt");
}
@Test
@TestMetadata("smartcastToTypeParameter.kt")
public void testSmartcastToTypeParameter() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/smartcasts/smartcastToTypeParameter.kt");
}
@Nested
@TestMetadata("compiler/fir/analysis-tests/testData/resolve/smartcasts/booleans")
@TestDataPath("$PROJECT_ROOT")
@@ -25651,6 +25651,18 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
runTest("compiler/testData/diagnostics/tests/smartCasts/smartcastOnSameFieldOfDifferentInstances.kt");
}
@Test
@TestMetadata("smartcastToInvisibleType_java.kt")
public void testSmartcastToInvisibleType_java() throws Exception {
runTest("compiler/testData/diagnostics/tests/smartCasts/smartcastToInvisibleType_java.kt");
}
@Test
@TestMetadata("smartcastToInvisibleType_kotlin.kt")
public void testSmartcastToInvisibleType_kotlin() throws Exception {
runTest("compiler/testData/diagnostics/tests/smartCasts/smartcastToInvisibleType_kotlin.kt");
}
@Test
@TestMetadata("smartcastToNothingAfterCheckingForNull.kt")
public void testSmartcastToNothingAfterCheckingForNull() throws Exception {
@@ -53,6 +53,10 @@ object FirReturnsImpliesAnalyzer : FirControlFlowChecker() {
override fun updateAllReceivers(flow: PersistentFlow) =
throw IllegalStateException("Update of all receivers is not possible for this logic system")
override fun ConeKotlinType.isAcceptableForSmartcast(): Boolean {
return true
}
}
effects.forEach { effect ->
@@ -37668,6 +37668,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/smartCasts/kt42517.kt");
}
@Test
@TestMetadata("kt44802.kt")
public void testKt44802() throws Exception {
runTest("compiler/testData/codegen/box/smartCasts/kt44802.kt");
}
@Test
@TestMetadata("kt44804.kt")
public void testKt44804() throws Exception {
@@ -13,7 +13,7 @@ import org.jetbrains.kotlin.fir.NoMutableState
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.getOwnerId
import org.jetbrains.kotlin.fir.resolve.calls.Candidate
import org.jetbrains.kotlin.fir.resolve.calls.ReceiverValue
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
@NoMutableState
@@ -23,7 +23,7 @@ object FirJavaVisibilityChecker : FirVisibilityChecker() {
symbol: AbstractFirBasedSymbol<*>,
useSiteFile: FirFile,
containingDeclarations: List<FirDeclaration>,
candidate: Candidate,
dispatchReceiver: ReceiverValue?,
session: FirSession
): Boolean {
return when (declarationVisibility) {
@@ -32,7 +32,7 @@ object FirJavaVisibilityChecker : FirVisibilityChecker() {
true
} else {
val ownerId = symbol.getOwnerId()
ownerId != null && canSeeProtectedMemberOf(containingDeclarations, candidate.dispatchReceiverValue, ownerId, session)
ownerId != null && canSeeProtectedMemberOf(containingDeclarations, dispatchReceiver, ownerId, session)
}
}
@@ -34,7 +34,7 @@ abstract class FirVisibilityChecker : FirSessionComponent {
symbol: AbstractFirBasedSymbol<*>,
useSiteFile: FirFile,
containingDeclarations: List<FirDeclaration>,
candidate: Candidate,
dispatchReceiver: ReceiverValue?,
session: FirSession
): Boolean {
return true
@@ -45,8 +45,6 @@ abstract class FirVisibilityChecker : FirSessionComponent {
declaration: T,
candidate: Candidate
): Boolean where T : FirMemberDeclaration, T : FirSymbolOwner<*> {
val symbol = declaration.symbol
if (declaration is FirCallableDeclaration<*> && (declaration.isIntersectionOverride || declaration.isSubstitutionOverride)) {
@Suppress("UNCHECKED_CAST")
return isVisible(declaration.originalIfFakeOverride() as T, candidate)
@@ -56,8 +54,19 @@ abstract class FirVisibilityChecker : FirSessionComponent {
val useSiteFile = callInfo.containingFile
val containingDeclarations = callInfo.containingDeclarations
val session = callInfo.session
val provider = session.firProvider
return isVisible(declaration, session, useSiteFile, containingDeclarations, candidate.dispatchReceiverValue)
}
fun <T> isVisible(
declaration: T,
session: FirSession,
useSiteFile: FirFile,
containingDeclarations: List<FirDeclaration>,
dispatchReceiver: ReceiverValue?
): Boolean where T : FirMemberDeclaration, T : FirSymbolOwner<*> {
val provider = session.firProvider
val symbol = declaration.symbol
return when (declaration.visibility) {
Visibilities.Internal -> {
declaration.session == session || session.moduleVisibilityChecker?.isInFriendModule(declaration) == true
@@ -91,7 +100,7 @@ abstract class FirVisibilityChecker : FirSessionComponent {
Visibilities.Protected -> {
val ownerId = symbol.getOwnerId()
ownerId != null && canSeeProtectedMemberOf(containingDeclarations, candidate.dispatchReceiverValue, ownerId, session)
ownerId != null && canSeeProtectedMemberOf(containingDeclarations, dispatchReceiver, ownerId, session)
}
else -> platformVisibilityCheck(
@@ -99,7 +108,7 @@ abstract class FirVisibilityChecker : FirSessionComponent {
symbol,
useSiteFile,
containingDeclarations,
candidate,
dispatchReceiver,
session
)
}
@@ -110,7 +119,7 @@ abstract class FirVisibilityChecker : FirSessionComponent {
symbol: AbstractFirBasedSymbol<*>,
useSiteFile: FirFile,
containingDeclarations: List<FirDeclaration>,
candidate: Candidate,
dispatchReceiver: ReceiverValue?,
session: FirSession
): Boolean
@@ -18,8 +18,7 @@ import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.languageVersionSettings
import org.jetbrains.kotlin.fir.references.FirControlFlowGraphReference
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.resolve.PersistentImplicitReceiverStack
import org.jetbrains.kotlin.fir.resolve.ResolutionMode
import org.jetbrains.kotlin.fir.resolve.*
import org.jetbrains.kotlin.fir.resolve.dfa.cfg.*
import org.jetbrains.kotlin.fir.resolve.dfa.contracts.buildContractFir
import org.jetbrains.kotlin.fir.resolve.dfa.contracts.createArgumentsMapping
@@ -31,6 +30,7 @@ import org.jetbrains.kotlin.fir.symbols.CallableId
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.visibilityChecker
import org.jetbrains.kotlin.fir.visitors.transformSingle
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
@@ -84,6 +84,9 @@ abstract class FirDataFlowAnalyzer<FLOW : Flow>(
private val receiverStack: PersistentImplicitReceiverStack
get() = components.implicitReceiverStack as PersistentImplicitReceiverStack
private val symbolProvider = components.session.symbolProvider
private val visibilityChecker = components.session.visibilityChecker
override val logicSystem: PersistentLogicSystem =
object : PersistentLogicSystem(components.session.inferenceComponents.ctx) {
override fun processUpdatedReceiverVariable(flow: PersistentFlow, variable: RealVariable) {
@@ -109,6 +112,27 @@ abstract class FirDataFlowAnalyzer<FLOW : Flow>(
}
}
}
override fun ConeKotlinType.isAcceptableForSmartcast(): Boolean {
return when (this) {
is ConeClassLikeType -> {
val symbol = fullyExpandedType(components.session).lookupTag.toSymbol(components.session) ?: return false
val declaration = symbol.fir as? FirRegularClass ?: return true
visibilityChecker.isVisible(
declaration,
components.session,
components.context.file,
components.context.containers,
dispatchReceiver = null
)
}
is ConeTypeParameterType -> true
is ConeFlexibleType -> lowerBound.isAcceptableForSmartcast() && upperBound.isAcceptableForSmartcast()
is ConeIntersectionType -> intersectedTypes.all { it.isAcceptableForSmartcast() }
is ConeDefinitelyNotNullType -> original.isAcceptableForSmartcast()
else -> false
}
}
}
}
}
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.fir.resolve.dfa
import org.jetbrains.kotlin.fir.types.ConeInferenceContext
import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.fir.types.canBeNull
import org.jetbrains.kotlin.fir.types.commonSuperTypeOrNull
abstract class Flow {
@@ -59,6 +60,8 @@ abstract class LogicSystem<FLOW : Flow>(protected val context: ConeInferenceCont
protected abstract fun getImplicationsWithVariable(flow: FLOW, variable: DataFlowVariable): Collection<Implication>
protected abstract fun ConeKotlinType.isAcceptableForSmartcast(): Boolean
// ------------------------------- Callbacks for updating implicit receiver stack -------------------------------
abstract fun processUpdatedReceiverVariable(flow: FLOW, variable: RealVariable)
@@ -150,7 +153,14 @@ abstract class LogicSystem<FLOW : Flow>(protected val context: ConeInferenceCont
}
}
val result = mutableSetOf<ConeKotlinType>()
context.commonSuperTypeOrNull(intersectedTypes)?.let { result.add(it) }
context.commonSuperTypeOrNull(intersectedTypes)?.let {
if (it.isAcceptableForSmartcast()) {
result.add(it)
} else if (!it.canBeNull) {
result.add(context.anyType())
}
Unit
}
return result
}
@@ -32,19 +32,19 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo
val symbolProvider: FirSymbolProvider get() = session.symbolProvider
override fun nullableNothingType(): SimpleTypeMarker {
override fun nullableNothingType(): ConeClassLikeType {
return session.builtinTypes.nullableNothingType.type
}
override fun nullableAnyType(): SimpleTypeMarker {
override fun nullableAnyType(): ConeClassLikeType {
return session.builtinTypes.nullableAnyType.type
}
override fun nothingType(): SimpleTypeMarker {
override fun nothingType(): ConeClassLikeType {
return session.builtinTypes.nothingType.type
}
override fun anyType(): SimpleTypeMarker {
override fun anyType(): ConeClassLikeType {
return session.builtinTypes.anyType.type
}
+46
View File
@@ -0,0 +1,46 @@
// TARGET_BACKEND: JVM
// ISSUE: KT-44802
// FILE: foo/Base.java
package foo;
public interface Base {
String foo();
}
// FILE: foo/PackagePrivateInterface.java
package foo;
interface PackagePrivateInterface extends Base {}
// FILE: foo/A.java
package foo;
public class A implements PackagePrivateInterface {
public String foo() { return "OK"; }
}
// FILE: foo/B.java
package foo;
public class B implements PackagePrivateInterface {
public String foo() { return "B"; }
}
// FILE: foo/C.java
package foo;
// FILE: main.kt
package bar
import foo.Base
import foo.A
import foo.B
fun testSmartcast(x: Base): String {
if (x !is A && x !is B) return "fail"
return x.foo()
}
fun box() = testSmartcast(A())
@@ -0,0 +1,53 @@
// ISSUE: KT-44802
// INFERENCE_HELPERS
// FILE: foo/PackagePrivateInterface.java
package foo;
interface PackagePrivateInterface {
default void foo() {}
}
// FILE: foo/A.java
package foo;
public class A implements PackagePrivateInterface {}
// FILE: foo/B.java
package foo;
public class B implements PackagePrivateInterface {}
// FILE: differentPackage.kt
package bar
import foo.A
import foo.B
import select
fun testSmartcast(x: Any) {
if (x is A || x is B) {
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any")!>x<!>.<!UNRESOLVED_REFERENCE!>foo<!>()
}
}
fun testInference(a: A, b: B) {
val x = <!DEBUG_INFO_EXPRESSION_TYPE("foo.PackagePrivateInterface")!>select(a, b)<!>
x.foo()
}
// FILE: samePackage.kt
package foo
import select
fun testSmartcast(x: Any) {
if (x is A || x is B) {
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any & foo.PackagePrivateInterface")!>x<!>.foo()
}
}
fun testInference(a: A, b: B) {
val x = <!DEBUG_INFO_EXPRESSION_TYPE("foo.PackagePrivateInterface")!>select(a, b)<!>
x.foo()
}
@@ -0,0 +1,53 @@
// ISSUE: KT-44802
// INFERENCE_HELPERS
// FILE: foo/PackagePrivateInterface.java
package foo;
interface PackagePrivateInterface {
default void foo() {}
}
// FILE: foo/A.java
package foo;
public class A implements PackagePrivateInterface {}
// FILE: foo/B.java
package foo;
public class B implements PackagePrivateInterface {}
// FILE: differentPackage.kt
package bar
import foo.A
import foo.B
import select
fun testSmartcast(x: Any) {
if (x is A || x is B) {
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any")!>x<!>.<!UNRESOLVED_REFERENCE!>foo<!>()
}
}
fun testInference(a: A, b: B) {
val x = <!DEBUG_INFO_EXPRESSION_TYPE("foo.PackagePrivateInterface"), INACCESSIBLE_TYPE!>select(a, b)<!>
<!INACCESSIBLE_TYPE!>x<!>.<!INVISIBLE_MEMBER!>foo<!>()
}
// FILE: samePackage.kt
package foo
import select
fun testSmartcast(x: Any) {
if (x is A || x is B) {
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any")!>x<!>.<!UNRESOLVED_REFERENCE!>foo<!>()
}
}
fun testInference(a: A, b: B) {
val x = <!DEBUG_INFO_EXPRESSION_TYPE("foo.PackagePrivateInterface")!>select(a, b)<!>
x.foo()
}
@@ -0,0 +1,39 @@
package
public fun </*0*/ K> id(/*0*/ x: K): K
public fun </*0*/ K> materialize(): K
public fun </*0*/ K> select(/*0*/ vararg values: K /*kotlin.Array<out K>*/): K
package bar {
public fun testInference(/*0*/ a: foo.A, /*1*/ b: foo.B): kotlin.Unit
public fun testSmartcast(/*0*/ x: kotlin.Any): kotlin.Unit
}
package foo {
public fun testInference(/*0*/ a: foo.A, /*1*/ b: foo.B): kotlin.Unit
public fun testSmartcast(/*0*/ x: kotlin.Any): kotlin.Unit
public open class A : foo.PackagePrivateInterface {
public constructor A()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun foo(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public open class B : foo.PackagePrivateInterface {
public constructor B()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun foo(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public/*package*/ interface PackagePrivateInterface {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open fun foo(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
@@ -0,0 +1,43 @@
// INFERENCE_HELPERS
// ISSUE: KT-44802
// FILE: a.kt
package foo
import select
private interface PrivateInterface {
fun foo() {}
}
class A : PrivateInterface
class B : PrivateInterface
fun testSmartcast(x: Any) {
if (x is A || x is B) {
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any & foo.PrivateInterface")!>x<!>.foo()
}
}
fun testInference(a: A, b: B) {
val x = <!DEBUG_INFO_EXPRESSION_TYPE("foo.PrivateInterface")!>select(a, b)<!>
x.foo()
}
// FILE: main.kt
package bar
import foo.A
import foo.B
import select
fun testSmartcast(x: Any) {
if (x is A || x is B) {
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any")!>x<!>.<!UNRESOLVED_REFERENCE!>foo<!>()
}
}
fun testInference(a: A, b: B) {
val x = <!DEBUG_INFO_EXPRESSION_TYPE("foo.PrivateInterface")!>select(a, b)<!>
x.foo()
}
@@ -0,0 +1,43 @@
// INFERENCE_HELPERS
// ISSUE: KT-44802
// FILE: a.kt
package foo
import select
private interface PrivateInterface {
fun foo() {}
}
class A : PrivateInterface
class B : PrivateInterface
fun testSmartcast(x: Any) {
if (x is A || x is B) {
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any")!>x<!>.<!UNRESOLVED_REFERENCE!>foo<!>()
}
}
fun testInference(a: A, b: B) {
val x = <!DEBUG_INFO_EXPRESSION_TYPE("foo.PrivateInterface")!>select(a, b)<!>
x.foo()
}
// FILE: main.kt
package bar
import foo.A
import foo.B
import select
fun testSmartcast(x: Any) {
if (x is A || x is B) {
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any")!>x<!>.<!UNRESOLVED_REFERENCE!>foo<!>()
}
}
fun testInference(a: A, b: B) {
val x = <!DEBUG_INFO_EXPRESSION_TYPE("foo.PrivateInterface")!>select(a, b)<!>
x.<!INVISIBLE_MEMBER!>foo<!>()
}
@@ -0,0 +1,39 @@
package
public fun </*0*/ K> id(/*0*/ x: K): K
public fun </*0*/ K> materialize(): K
public fun </*0*/ K> select(/*0*/ vararg values: K /*kotlin.Array<out K>*/): K
package bar {
public fun testInference(/*0*/ a: foo.A, /*1*/ b: foo.B): kotlin.Unit
public fun testSmartcast(/*0*/ x: kotlin.Any): kotlin.Unit
}
package foo {
public fun testInference(/*0*/ a: foo.A, /*1*/ b: foo.B): kotlin.Unit
public fun testSmartcast(/*0*/ x: kotlin.Any): kotlin.Unit
public final class A : foo.PrivateInterface {
public constructor A()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun foo(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class B : foo.PrivateInterface {
public constructor B()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun foo(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
private interface PrivateInterface {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open fun foo(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
@@ -25741,6 +25741,18 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
runTest("compiler/testData/diagnostics/tests/smartCasts/smartcastOnSameFieldOfDifferentInstances.kt");
}
@Test
@TestMetadata("smartcastToInvisibleType_java.kt")
public void testSmartcastToInvisibleType_java() throws Exception {
runTest("compiler/testData/diagnostics/tests/smartCasts/smartcastToInvisibleType_java.kt");
}
@Test
@TestMetadata("smartcastToInvisibleType_kotlin.kt")
public void testSmartcastToInvisibleType_kotlin() throws Exception {
runTest("compiler/testData/diagnostics/tests/smartCasts/smartcastToInvisibleType_kotlin.kt");
}
@Test
@TestMetadata("smartcastToNothingAfterCheckingForNull.kt")
public void testSmartcastToNothingAfterCheckingForNull() throws Exception {
@@ -37668,6 +37668,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/smartCasts/kt42517.kt");
}
@Test
@TestMetadata("kt44802.kt")
public void testKt44802() throws Exception {
runTest("compiler/testData/codegen/box/smartCasts/kt44802.kt");
}
@Test
@TestMetadata("kt44804.kt")
public void testKt44804() throws Exception {
@@ -37668,6 +37668,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/smartCasts/kt42517.kt");
}
@Test
@TestMetadata("kt44802.kt")
public void testKt44802() throws Exception {
runTest("compiler/testData/codegen/box/smartCasts/kt44802.kt");
}
@Test
@TestMetadata("kt44804.kt")
public void testKt44804() throws Exception {
@@ -30120,6 +30120,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/smartCasts/kt42517.kt");
}
@TestMetadata("kt44802.kt")
public void testKt44802() throws Exception {
runTest("compiler/testData/codegen/box/smartCasts/kt44802.kt");
}
@TestMetadata("kt44804.kt")
public void testKt44804() throws Exception {
runTest("compiler/testData/codegen/box/smartCasts/kt44804.kt");