Compiler error: smart cast is impossible

I have two Kotlin classes in the same package:

Foo.kt:

data class Foo(
    val map: Map<String, String>? = null
)

Bar.kt:

class Bar {
    init {
        val foo = Foo()
        if (filter.map != null) {
            val value = filter.map["some_key"] // IDE shows successful smart cast here
        }
    }
}

Then trying to compile only one class Bar.kt:

kotlinc Bar.kt -d output

Class Foo.kt resides in the same package, but nevertheless I’m getting the following compiler error:

error: smart cast to 'Map<String, String>' is impossible, because '...' is a public API property declared in different module

However compiling both classes completes successfully:

kotlinc Bar.kt Foo.kt -d output // OK

So, my question: is it possible to compile only one Bar.kt class without smart cast error?

As the error says, if you don’t specify both files, the compiler doesn’t consider them a part of the same module. And files from the same module have some special “privileges” that are not available otherwise, for example smart casting of properties in some cases.

You can use ?.let() instead of smart casting:

filter.map?.let { val value = it["some_key"] }
2 Likes

Looks like this advanced compiler option can help me in my question:
-Xsingle-module // Combine modules for source files and binary dependencies into a single module

Unfortunately it causes a crash in the latest version of kotlinc.
Already reported: https://youtrack.jetbrains.com/issue/KT-51622

2 Likes

Following

When compiling only partial files, you can use -Xfriend-paths to point to the output directory to avoid this problem.

May be like this:
kotlinc Bar.kt -d output -Xfriend-paths=out

I had this problem for a few weeks :rofl:, and I finally found this key argument while looking at the source code in the JetBrains/kotlin repository.
kotlin/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.kt at master · JetBrains/kotlin (github.com)