Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

K2: a @JvmField actual companion property, read from common code, is read through a getter it does not have

Open
#96 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
32/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Active
Tech stack
java, kotlin
Domain
compilers, tooling

Research direction

Reproduce with the given commonMain/jvmMain expect/actual Listener.Factory.NONE fixture and compare the IR/access path to coil’s EventListener.Factory.NONE (nonAndroidMain) after the TestCoilJvmSlice fix. Trace where an expect companion property still synthesizes a getter instead of taking @JvmField/const from the actual (readAsField) and falling back to the enclosing interface’s static field. Done when common-code reads of the actual @JvmField companion use Listener.Factory.NONE with no getter.

Written by the indexing model from the issue text.

Description

A @JvmField actual companion property read from common code is read through a getter it does not have, in a minimal multiplatform fixture:

// commonMain
expect abstract class Listener {
    fun interface Factory {
        fun create(): Listener
        companion object { val NONE: Factory }
    }
}
class User { fun none(f: Listener.Factory?): Listener.Factory = f ?: Listener.Factory.NONE }

// jvmMain
actual abstract class Listener {
    actual fun interface Factory {
        actual fun create(): Listener
        actual companion object { @JvmField actual val NONE = Factory { object : Listener() {} } }
    }
}

User.none converts to return f==null?Factory.Companion.getNONE():f;. kotlinc compiles a @JvmField companion property to a public static field of the enclosing interface, with no getter, so the read should be the field Listener.Factory.NONE.

The same source shape in coil (EventListener.Factory.NONE, nonAndroidMain actual) took a different path: no getter was found there either, so it was a k2-unresolved-access:NONE placeholder. Since the fix for TestCoilJvmSlice, a companion with no getter for the name falls back to the enclosing class's static field, and coil reads the field. This fixture, however, still finds a getter, most likely one built from the expect companion's declaration, which has no @JvmField.

Likely direction: when an expect property has an actual, take @JvmField/const from the actual (readAsField), and do not synthesize accessors for an expect companion property whose actual is a @JvmField.

Dominant language
Java
Stars
1
Forks
1
Avg merge
2h 51m
Merged PRs (30d)
3

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from CodeLaser/maddi

All issues in CodeLaser/maddi

Similar issues

More Java issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.