title: How does Kotlin dispatch the invoke operator?
body: <p>How does Kotlin disambiguate function calls, constructors, companion objects and invocation overloads? In Kotlin <code>1.3.11</code>, I can declare two homonymous members in the same scope:</p>
  
  <pre><code>fun main(args: Array&lt;String&gt;) {
      val test = object {
          operator fun invoke() = println("test invocation")
      }
  
      test() // Prints: "test invocation"
  
      // I think this should fail to compile, but it works
      fun test() = println("test function")
  
      test() // Prints: "test function"
  }
  </code></pre>
  
  <p>You might think it uses the most recent declaration, but not so!</p>
  
  <pre><code>fun main(args: Array&lt;String&gt;) {
      fun test() = println("test function")
  
      val test = object {
          operator fun invoke() = println("test invocation")
      }
  
      test() // Prints: "test function"
  }
  </code></pre>
  
  <p>But there is also some weird interaction with scope. If I move the function declaration outside:</p>
  
  <pre><code>fun test() = println("test function")
  
  fun main(args: Array&lt;String&gt;) {
      val test = object {
          operator fun invoke() = println("test invocation")
      }
  
      test() // Prints "test invocation"
  }
  </code></pre>
  
  <p>Similarly, if I move the object outside, this also compiles:</p>
  
  <pre><code>val test = object {
      operator fun invoke() = println("test invocation")
  }
  
  fun main(args: Array&lt;String&gt;) {
      fun test() = println("test function")
      test() // Prints: "test function"
  }
  </code></pre>
  
  <p>I can also move them both outside:</p>
  
  <pre><code>val test = object {
      operator fun invoke() = println("test invocation")
  }
  
  fun test() = println("test function")
  
  fun main(args: Array&lt;String&gt;) {
      test() // Prints: "test function"
  }
  </code></pre>
  
  <p>But if I overload <code>test</code> using a class name, it does not compile: </p>
  
  <pre><code>class test {} // Does not compile
  
  fun test() = println("test function")
  
  val test = object {
      operator fun invoke() = println("test invocation")
  }
  </code></pre>
  
  <p>Attempting to compile this program results in the following error:</p>
  
  <pre><code>Error:(1, 6) Conflicting overloads: public fun test(): Unit defined in root package in file Simplest version.kt, public constructor test() defined in test, public val test: Any defined in root package in file Simplest version.kt, public final class test defined in root package in file Simplest version.kt
  Error:(1, 6) Conflicting declarations: public fun test(): Unit, public constructor test(), public val test: Any, public final class test
  Error:(2, 0) Conflicting overloads: public fun test(): Unit defined in root package in file Simplest version.kt, public constructor test() defined in test, public val test: Any defined in root package in file Simplest version.kt, public final class test defined in root package in file Simplest version.kt
  Error:(3, 4) Conflicting declarations: public fun test(): Unit, public constructor test(), public val test: Any, public final class test
  </code></pre>
  
  <p>However it does compile when using a nested scope:</p>
  
  <pre><code>class test {
      constructor() {
          println("test constructor")
      }
  }
  
  fun main(args: Array&lt;String&gt;) {
      fun test() = println("test function")
  
      val test = object {
          operator fun invoke() = println("test invocation")
      }
  
      test() // Prints: "test function"
  }
  </code></pre>
  
  <p>There is also some ambiguity between companion objects and constructors:</p>
  
  <pre><code>class test {
      constructor() {
          println("test constructor")
      }
  
      companion object {
          operator fun invoke() = println("test companion invocation")
      }
  }
  
  fun main(args: Array&lt;String&gt;) {
      test() // Prints: "test constructor"
  }
  </code></pre>
  
  <p>Somehow, the following example also compiles:</p>
  
  <pre><code>class test {
      constructor() {
          println("test constructor")
      }
  
      companion object {
          operator fun invoke() = println("test companion invocation")
      }
  }
  
  fun main(args: Array&lt;String&gt;) {
      test() // Prints: "test constructor"
  
      val test = object {
          operator fun invoke() = println("test invocation")
      }
  
      test() // Prints: "test invocation"
  
      fun test() = println("test function")
  
      test() // Prints: "test function"
  }
  </code></pre>
  
  <p>This is even less intuitive:</p>
  
  <pre><code>class test {
      constructor() {
          println("test constructor")
      }
  
      companion object {
          operator fun invoke() = println("test companion invocation")
      }
  
      operator fun invoke() = println("test invocation overload")
  }
  
  fun main(args: Array&lt;String&gt;) {
      val test = test() // Prints: "test constructor"
  
      val test1 = test() // Prints: "test invocation overload"
  }
  </code></pre>
  
  <p>What are the rules for overloading named members and why will the Kotlin compiler accept invocable variables and homonymous functions in the same scope, but not in the presence of a homonymous class (in certain cases, but not others)? Also, how does invoke work in the presence of a scoped constructor or companion object with the same call site syntax?</p>