diff --git a/compiler/fir/resolve/testData/resolve/stdlib/problems/complexSmartCasts.kt b/compiler/fir/resolve/testData/resolve/stdlib/problems/complexSmartCasts.kt new file mode 100644 index 00000000000..165543e7a17 --- /dev/null +++ b/compiler/fir/resolve/testData/resolve/stdlib/problems/complexSmartCasts.kt @@ -0,0 +1,57 @@ +fun runHigherOrder(f: () -> T): T = f() + +val String.ext: Int get() = length + +fun foo(a: Any?) { + val s = a as? String + val length = s?.ext ?: return + runHigherOrder { + s.isNotEmpty() + } +} + +fun bar(s: String?) { + if (s?.isNotEmpty() == true) { + s.length + } +} + +fun baz(s: String?) { + when { + !s.isNullOrEmpty() -> s.length + } +} + +fun bazz(s: String?) { + s?.let { use(it) } +} + +class Wrapper(val s: String?) { + fun withThis() { + if (s != null) { + use(this.s) + } + if (this.s != null) { + use(s) + } + } +} + +fun Any.withInvoke(f: String.() -> Unit) { + if (this is String) { + f() + } +} + +fun String.withInvoke(f: String.() -> Unit) { + f() +} + +fun withBangBang(a: X) { + if (a is String?) { + use(a!!) + } +} + +fun use(s: String) {} + diff --git a/compiler/fir/resolve/testData/resolve/stdlib/problems/complexSmartCasts.txt b/compiler/fir/resolve/testData/resolve/stdlib/problems/complexSmartCasts.txt new file mode 100644 index 00000000000..f041a578478 --- /dev/null +++ b/compiler/fir/resolve/testData/resolve/stdlib/problems/complexSmartCasts.txt @@ -0,0 +1,91 @@ +FILE: complexSmartCasts.kt + public final fun runHigherOrder(f: R|() -> T|): R|T| { + ^runHigherOrder R|/f|.R|FakeOverride|() + } + public final val R|kotlin/String|.ext: R|kotlin/Int| + public get(): R|kotlin/Int| { + ^ this@R|/ext|.R|kotlin/String.length| + } + public final fun foo(a: R|kotlin/Any?|): R|kotlin/Unit| { + lval s: R|kotlin/String?| = (R|/a| as? R|kotlin/String|) + lval length: R|kotlin/Int| = when (lval : R|kotlin/Int?| = R|/s|?.R|/ext|) { + ==($subj$, Null(null)) -> { + ^foo Unit + } + else -> { + R|/| + } + } + + R|/runHigherOrder|( = runHigherOrder@fun (): R|kotlin/Boolean| { + R|/s|.R|kotlin/text/isNotEmpty|() + } + ) + } + public final fun bar(s: R|kotlin/String?|): R|kotlin/Unit| { + when () { + ==(R|/s|?.R|kotlin/text/isNotEmpty|(), Boolean(true)) -> { + R|/s|.# + } + } + + } + public final fun baz(s: R|kotlin/String?|): R|kotlin/Unit| { + when () { + R|/s|.R|kotlin/text/isNullOrEmpty|().R|kotlin/Boolean.not|() -> { + R|/s|.# + } + } + + } + public final fun bazz(s: R|kotlin/String?|): R|kotlin/Unit| { + R|/s|?.R|kotlin/let|( = let@fun (it: R|kotlin/String|): R|kotlin/Unit| { + R|/use|(R|/it|) + } + ) + } + public final class Wrapper : R|kotlin/Any| { + public constructor(s: R|kotlin/String?|): R|Wrapper| { + super() + } + + public final val s: R|kotlin/String?| = R|/s| + public get(): R|kotlin/String?| + + public final fun withThis(): R|kotlin/Unit| { + when () { + !=(this@R|/Wrapper|.R|/Wrapper.s|, Null(null)) -> { + R|/use|(this@R|/Wrapper|.R|/Wrapper.s|) + } + } + + when () { + !=(this@R|/Wrapper|.R|/Wrapper.s|, Null(null)) -> { + R|/use|(this@R|/Wrapper|.R|/Wrapper.s|) + } + } + + } + + } + public final fun R|kotlin/Any|.withInvoke(f: R|kotlin/String.() -> kotlin/Unit|): R|kotlin/Unit| { + when () { + (this@R|/withInvoke| is R|kotlin/String|) -> { + #() + } + } + + } + public final fun R|kotlin/String|.withInvoke(f: R|kotlin/String.() -> kotlin/Unit|): R|kotlin/Unit| { + R|/f|.R|FakeOverride|(this@R|/withInvoke|) + } + public final fun withBangBang(a: R|X|): R|kotlin/Unit| { + when () { + (R|/a| is R|kotlin/String?|) -> { + #(R|/a|!!) + } + } + + } + public final fun use(s: R|kotlin/String|): R|kotlin/Unit| { + } diff --git a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithStdlibTestGenerated.java b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithStdlibTestGenerated.java index f13578b9a2e..d7c07944881 100644 --- a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithStdlibTestGenerated.java +++ b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithStdlibTestGenerated.java @@ -627,6 +627,11 @@ public class FirDiagnosticsWithStdlibTestGenerated extends AbstractFirDiagnostic runTest("compiler/fir/resolve/testData/resolve/stdlib/problems/cloneArray.kt"); } + @TestMetadata("complexSmartCasts.kt") + public void testComplexSmartCasts() throws Exception { + runTest("compiler/fir/resolve/testData/resolve/stdlib/problems/complexSmartCasts.kt"); + } + @TestMetadata("delegateTypeMismatch.kt") public void testDelegateTypeMismatch() throws Exception { runTest("compiler/fir/resolve/testData/resolve/stdlib/problems/delegateTypeMismatch.kt");