Generic function extension assign to private property


#1

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:


#2

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.


#3

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 ?


#4

Yep :wink: You obviously found a bug.


#5

–> Issue created