Generic function extension assign to private property

Hello, I recently stumbled upon a weird case. Here’s the snippet:


You can also find reproducer here

We have an extension function on a generic named myName.
Language version 1.3.0-rc90
If I specify property type explicitely it works
What happens is:

  1. If I assign it to a private property with the same name on a class with declaration-site variance → fails
  2. If I assign it to a private property with a different name on a class with declaration-site variance → ok
  3. If I assign it to a (protected | internal | public) property with a same name on a class with declaration-site variance → ok
  4. If I assign it to a private property with the same name on a class without declaration-site variance → ok

Thanks for a feedback :smiley:

Next time, try to use the build in code blocks support rather than an image.

It seems like you’ve found a bug/inconsistency in terms of the variance. One thing to check would be whether it still fails if you rename the T in your extension function to something else (U). My impression is that if 2-3 pass then 1 must pass as well. But there is an overload resolution issue (remember that in Kotlin it is valid for values to be invoked - with the invoke operator as member or extension) that you just happen to avert because the property doesn’t exist yet on the right hand side of its initialisation.

Hi and thank you very much for the quick reply.
I’ve updated reproducer with your recommendations but it still fails. Here’s the current scenario (in code blocks this time :D)

inline fun <reified U> U.myName(): String = U::class.simpleName ?: "simpleName"

class User<out T>() {

    companion object {
        // this works
        private val myName = myName()
    }

    // this FAILS
    // with Type checking has run into a recursive problem. Easiest workaround: specify types of your declarations explicitly
    private val myName = myName()

    // this works with explicit type
    private val myName: String = myName()

    // this works
    private val myOtherName = myName()

//    this works
//    (either public or internal or protected) val myName = myName()
}

class Person<T>() {
    // this works
    private val myName = myName()
}

Is it worth opening an issue on youtrack ?

Yep :wink: You obviously found a bug.

Issue created