diff --git a/compiler/fir/resolve/testData/resolve/lambdaArgInScopeFunction.kt b/compiler/fir/resolve/testData/resolve/lambdaArgInScopeFunction.kt new file mode 100644 index 00000000000..71a3c91a16e --- /dev/null +++ b/compiler/fir/resolve/testData/resolve/lambdaArgInScopeFunction.kt @@ -0,0 +1,40 @@ +// !CHECK_TYPE +// ISSUE: KT-37070 + +class KotlinClass(private val name: String) : Comparable { + override operator fun compareTo(that: KotlinClass): Int { + return name.compareTo(that.name) + } +} + + +// TESTCASE NUMBER: 1 +fun case1(kotlinClass: KotlinClass?) { + + val value = kotlinClass?.let { + it + } + + value.checkType { _() } + + val lambda = kotlinClass?.let { + {it} + } + + lambda.checkType { _>() } +} +// TESTCASE NUMBER: 2 +fun case2(kotlinClass: KotlinClass) { + + val value = kotlinClass.let { + it + } + + value.checkType { _() } + + val lambda = kotlinClass.let { + {it} + } + + lambda.checkType { _>() } +} \ No newline at end of file diff --git a/compiler/fir/resolve/testData/resolve/lambdaArgInScopeFunction.txt b/compiler/fir/resolve/testData/resolve/lambdaArgInScopeFunction.txt new file mode 100644 index 00000000000..d3ccf247c59 --- /dev/null +++ b/compiler/fir/resolve/testData/resolve/lambdaArgInScopeFunction.txt @@ -0,0 +1,70 @@ +FILE: lambdaArgInScopeFunction.kt + public final class KotlinClass : R|kotlin/Comparable| { + public constructor(name: R|kotlin/String|): R|KotlinClass| { + super() + } + + private final val name: R|kotlin/String| = R|/name| + private get(): R|kotlin/String| + + public final override operator fun compareTo(that: R|KotlinClass|): R|kotlin/Int| { + ^compareTo this@R|/KotlinClass|.R|/KotlinClass.name|.R|kotlin/String.compareTo|(R|/that|.R|/KotlinClass.name|) + } + + } + public final fun case1(kotlinClass: R|KotlinClass?|): R|kotlin/Unit| { + lval value: R|KotlinClass?| = R|/kotlinClass|?.R|kotlin/let|( = let@fun (it: R|KotlinClass|): R|KotlinClass| { + ^ R|/it| + } + ) + R|/value|.R|tests/_checkType/checkType|( = checkType@fun R|tests/_checkType/Inv|.(): R|kotlin/Unit| { + this@R|special/anonymous|.R|tests/_checkType/_|() + } + ) + lval lambda: R|kotlin/Nothing?| = R|/kotlinClass|?.R|kotlin/let|( = let@fun (it: R|KotlinClass|): R|kotlin/Nothing| { + ^ let@fun (): { + ^ # + } + + } + ) + R|/lambda|.R|tests/_checkType/checkType|( = checkType@fun R|tests/_checkType/Inv|.(): R|kotlin/Unit| { + ^ # KotlinClass?|>() + } + ) + } + public final fun case2(kotlinClass: R|KotlinClass|): R|kotlin/Unit| { + lval value: R|KotlinClass| = R|/kotlinClass|.R|kotlin/let|( = let@fun (it: R|KotlinClass|): R|KotlinClass| { + ^ R|/it| + } + ) + R|/value|.R|tests/_checkType/checkType|( = checkType@fun R|tests/_checkType/Inv|.(): R|kotlin/Unit| { + this@R|special/anonymous|.R|tests/_checkType/_|() + } + ) + lval lambda: R|kotlin/Nothing| = R|/kotlinClass|.R|kotlin/let|( = let@fun (it: R|KotlinClass|): R|kotlin/Nothing| { + ^ let@fun (): { + ^ # + } + + } + ) + R|/lambda|.R|tests/_checkType/checkType|( = checkType@fun R|tests/_checkType/Inv|.(): R|kotlin/Unit| { + ^ # KotlinClass?|>() + } + ) + } +FILE: CHECK_TYPE.kt + public final fun checkSubtype(t: R|T|): R|T| { + ^checkSubtype R|/t| + } + public final class Inv : R|kotlin/Any| { + public constructor(): R|tests/_checkType/Inv| { + super() + } + + } + public final fun R|tests/_checkType/Inv|._(): R|kotlin/Unit| { + } + public final infix fun R|T|.checkType(f: R|tests/_checkType/Inv.() -> kotlin/Unit|): R|kotlin/Unit| { + } diff --git a/compiler/fir/resolve/testData/resolve/lambdaPropertyTypeInference.kt b/compiler/fir/resolve/testData/resolve/lambdaPropertyTypeInference.kt new file mode 100644 index 00000000000..77d58e48972 --- /dev/null +++ b/compiler/fir/resolve/testData/resolve/lambdaPropertyTypeInference.kt @@ -0,0 +1,71 @@ +// !CHECK_TYPE +// UNEXPECTED BEHAVIOUR +// ISSUES: KT-37066 + +// TESTCASE NUMBER: 1 +// FILE: JavaClass.java +public final class JavaClass implements Comparable { + private final String name; + + public JavaClass (String name) { + this.name = name; + } + + @Override + public int compareTo(JavaClass that) { + return this.name.compareTo(that.name); + } +} + + +// FILE: KotlinClass.kt +fun case1(javaClass: JavaClass?) { + val validType: (JavaClass) -> Boolean = if (javaClass != null) { it -> it == javaClass } else BooCase1.FILTER + + val invalidType = if (javaClass != null) { it -> it == javaClass } else BooCase1.FILTER + + validType.checkType { _>() } //ok + + invalidType.checkType { _>() } //(!!!) + + Case1(javaClass).x.checkType { _>() } //(!!!) +} + +class Case1(val javaClass: JavaClass?) { + val x = if (javaClass != null) { it -> it == javaClass } else BooCase2.FILTER +} + +class BooCase1() { + companion object { + val FILTER: (JavaClass) -> Boolean = { true } + } +} + +// TESTCASE NUMBER: 2 + +class KotlinClass(private val name: String) : Comparable { + override operator fun compareTo(that: KotlinClass): Int { + return name.compareTo(that.name) + } +} + +fun case2(kotlinClass: KotlinClass?) { + val validType: (KotlinClass) -> Boolean = if (kotlinClass != null) { it -> it == kotlinClass } else BooCase2.FILTER + val invalidType = if (kotlinClass != null) { it -> it == kotlinClass } else BooCase2.FILTER + + validType.checkType { _>() } //ok + + invalidType.checkType { _>() } //(!!!) + + Case2(kotlinClass).x.checkType { _>() } //(!!!) +} + +class Case2(val kotlinClass: KotlinClass?) { + val x = if (kotlinClass != null) { it -> it == kotlinClass } else BooCase2.FILTER +} + +class BooCase2() { + companion object { + val FILTER: (KotlinClass) -> Boolean = { true } + } +} diff --git a/compiler/fir/resolve/testData/resolve/lambdaPropertyTypeInference.txt b/compiler/fir/resolve/testData/resolve/lambdaPropertyTypeInference.txt new file mode 100644 index 00000000000..528aa86de97 --- /dev/null +++ b/compiler/fir/resolve/testData/resolve/lambdaPropertyTypeInference.txt @@ -0,0 +1,188 @@ +FILE: KotlinClass.kt + public final fun case1(javaClass: R|JavaClass?|): R|kotlin/Unit| { + lval validType: R|(JavaClass) -> kotlin/Boolean| = when () { + !=(R|/javaClass|, Null(null)) -> { + fun (it: R|kotlin/Nothing|): R|kotlin/Boolean| { + ^ ==(R|/it|, R|/javaClass|) + } + + } + else -> { + Q|BooCase1|.R|/BooCase1.Companion.FILTER| + } + } + + lval invalidType: R|(kotlin/Nothing) -> kotlin/Boolean| = when () { + !=(R|/javaClass|, Null(null)) -> { + fun (it: R|kotlin/Nothing|): R|kotlin/Boolean| { + ^ ==(R|/it|, R|/javaClass|) + } + + } + else -> { + Q|BooCase1|.R|/BooCase1.Companion.FILTER| + } + } + + R|/validType|.R|tests/_checkType/checkType| kotlin/Boolean|>( = checkType@fun R|tests/_checkType/Inv>|.(): R|kotlin/Unit| { + this@R|special/anonymous|.R|tests/_checkType/_| kotlin/Boolean|>() + } + ) + R|/invalidType|.R|tests/_checkType/checkType| kotlin/Boolean|>( = checkType@fun R|tests/_checkType/Inv>|.(): R|kotlin/Unit| { + this@R|special/anonymous|.R|tests/_checkType/_| kotlin/Boolean|>() + } + ) + R|/Case1.Case1|(R|/javaClass|).R|/Case1.x|.R|tests/_checkType/checkType| kotlin/Boolean|>( = checkType@fun R|tests/_checkType/Inv>|.(): R|kotlin/Unit| { + this@R|special/anonymous|.R|tests/_checkType/_| kotlin/Boolean|>() + } + ) + } + public final class Case1 : R|kotlin/Any| { + public constructor(javaClass: R|JavaClass?|): R|Case1| { + super() + } + + public final val javaClass: R|JavaClass?| = R|/javaClass| + public get(): R|JavaClass?| + + public final val x: R|(kotlin/Nothing) -> kotlin/Boolean| = when () { + !=(R|/javaClass|, Null(null)) -> { + fun (it: R|kotlin/Nothing|): R|kotlin/Boolean| { + ^ ==(R|/it|, R|/javaClass|) + } + + } + else -> { + Q|BooCase2|.R|/BooCase2.Companion.FILTER| + } + } + + public get(): R|(kotlin/Nothing) -> kotlin/Boolean| + + } + public final class BooCase1 : R|kotlin/Any| { + public constructor(): R|BooCase1| { + super() + } + + public final companion object Companion : R|kotlin/Any| { + private constructor(): R|BooCase1.Companion| { + super() + } + + public final val FILTER: R|(JavaClass) -> kotlin/Boolean| = fun (it: R|JavaClass|): R|kotlin/Boolean| { + ^ Boolean(true) + } + + public get(): R|(JavaClass) -> kotlin/Boolean| + + } + + } + public final class KotlinClass : R|kotlin/Comparable| { + public constructor(name: R|kotlin/String|): R|KotlinClass| { + super() + } + + private final val name: R|kotlin/String| = R|/name| + private get(): R|kotlin/String| + + public final override operator fun compareTo(that: R|KotlinClass|): R|kotlin/Int| { + ^compareTo this@R|/KotlinClass|.R|/KotlinClass.name|.R|kotlin/String.compareTo|(R|/that|.R|/KotlinClass.name|) + } + + } + public final fun case2(kotlinClass: R|KotlinClass?|): R|kotlin/Unit| { + lval validType: R|(KotlinClass) -> kotlin/Boolean| = when () { + !=(R|/kotlinClass|, Null(null)) -> { + fun (it: R|kotlin/Nothing|): R|kotlin/Boolean| { + ^ ==(R|/it|, R|/kotlinClass|) + } + + } + else -> { + Q|BooCase2|.R|/BooCase2.Companion.FILTER| + } + } + + lval invalidType: R|(kotlin/Nothing) -> kotlin/Boolean| = when () { + !=(R|/kotlinClass|, Null(null)) -> { + fun (it: R|kotlin/Nothing|): R|kotlin/Boolean| { + ^ ==(R|/it|, R|/kotlinClass|) + } + + } + else -> { + Q|BooCase2|.R|/BooCase2.Companion.FILTER| + } + } + + R|/validType|.R|tests/_checkType/checkType| kotlin/Boolean|>( = checkType@fun R|tests/_checkType/Inv>|.(): R|kotlin/Unit| { + this@R|special/anonymous|.R|tests/_checkType/_| kotlin/Boolean|>() + } + ) + R|/invalidType|.R|tests/_checkType/checkType| kotlin/Boolean|>( = checkType@fun R|tests/_checkType/Inv>|.(): R|kotlin/Unit| { + this@R|special/anonymous|.R|tests/_checkType/_| kotlin/Boolean|>() + } + ) + R|/Case2.Case2|(R|/kotlinClass|).R|/Case2.x|.R|tests/_checkType/checkType| kotlin/Boolean|>( = checkType@fun R|tests/_checkType/Inv>|.(): R|kotlin/Unit| { + this@R|special/anonymous|.R|tests/_checkType/_| kotlin/Boolean|>() + } + ) + } + public final class Case2 : R|kotlin/Any| { + public constructor(kotlinClass: R|KotlinClass?|): R|Case2| { + super() + } + + public final val kotlinClass: R|KotlinClass?| = R|/kotlinClass| + public get(): R|KotlinClass?| + + public final val x: R|(kotlin/Nothing) -> kotlin/Boolean| = when () { + !=(R|/kotlinClass|, Null(null)) -> { + fun (it: R|kotlin/Nothing|): R|kotlin/Boolean| { + ^ ==(R|/it|, R|/kotlinClass|) + } + + } + else -> { + Q|BooCase2|.R|/BooCase2.Companion.FILTER| + } + } + + public get(): R|(kotlin/Nothing) -> kotlin/Boolean| + + } + public final class BooCase2 : R|kotlin/Any| { + public constructor(): R|BooCase2| { + super() + } + + public final companion object Companion : R|kotlin/Any| { + private constructor(): R|BooCase2.Companion| { + super() + } + + public final val FILTER: R|(KotlinClass) -> kotlin/Boolean| = fun (it: R|KotlinClass|): R|kotlin/Boolean| { + ^ Boolean(true) + } + + public get(): R|(KotlinClass) -> kotlin/Boolean| + + } + + } +FILE: CHECK_TYPE.kt + public final fun checkSubtype(t: R|T|): R|T| { + ^checkSubtype R|/t| + } + public final class Inv : R|kotlin/Any| { + public constructor(): R|tests/_checkType/Inv| { + super() + } + + } + public final fun R|tests/_checkType/Inv|._(): R|kotlin/Unit| { + } + public final infix fun R|T|.checkType(f: R|tests/_checkType/Inv.() -> kotlin/Unit|): R|kotlin/Unit| { + } diff --git a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java index 520c073e471..29e1d2359bf 100644 --- a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java +++ b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java @@ -218,6 +218,16 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest { runTest("compiler/fir/resolve/testData/resolve/javaStaticScopeInheritance.kt"); } + @TestMetadata("lambdaArgInScopeFunction.kt") + public void testLambdaArgInScopeFunction() throws Exception { + runTest("compiler/fir/resolve/testData/resolve/lambdaArgInScopeFunction.kt"); + } + + @TestMetadata("lambdaPropertyTypeInference.kt") + public void testLambdaPropertyTypeInference() throws Exception { + runTest("compiler/fir/resolve/testData/resolve/lambdaPropertyTypeInference.kt"); + } + @TestMetadata("localFunctionsHiding.kt") public void testLocalFunctionsHiding() throws Exception { runTest("compiler/fir/resolve/testData/resolve/localFunctionsHiding.kt"); diff --git a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithLightTreeTestGenerated.java b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithLightTreeTestGenerated.java index 6bb37555d5d..2f073cf5dc7 100644 --- a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithLightTreeTestGenerated.java +++ b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithLightTreeTestGenerated.java @@ -218,6 +218,16 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos runTest("compiler/fir/resolve/testData/resolve/javaStaticScopeInheritance.kt"); } + @TestMetadata("lambdaArgInScopeFunction.kt") + public void testLambdaArgInScopeFunction() throws Exception { + runTest("compiler/fir/resolve/testData/resolve/lambdaArgInScopeFunction.kt"); + } + + @TestMetadata("lambdaPropertyTypeInference.kt") + public void testLambdaPropertyTypeInference() throws Exception { + runTest("compiler/fir/resolve/testData/resolve/lambdaPropertyTypeInference.kt"); + } + @TestMetadata("localFunctionsHiding.kt") public void testLocalFunctionsHiding() throws Exception { runTest("compiler/fir/resolve/testData/resolve/localFunctionsHiding.kt");