title: Trouble with operator overloading and inferred types in Swift
body: <h2>Literals</h2>
  
  <p>Swift has a couple of <em>literals</em> that can be used to initialize different types without explicitly calling their initializer. For example, </p>
  
  <pre><code>let x = 5             // x is now an Int
  </code></pre>
  
  <p>automatically infers <code>x</code> to be of type <code>Int</code>. But if we specify the type of the variable to be something else</p>
  
  <pre><code>let x: UInt = 5       // x is now a UInt
  </code></pre>
  
  <p>the compiler automatically understands that <code>5</code> is now an unsigned integer and so the respective <code>UInt</code> initializer has to be called instead of the <code>Int</code> initializer.</p>
  
  <hr>
  
  <h2>The <code>ExpressibleByIntegerLiteral</code> protocol</h2>
  
  <p>This is possible for all types that implement the protocol <code>ExpressibleByIntegerLiteral</code>. Now I add this protocol conformance to my own type:</p>
  
  <pre><code>/// Represents a range of characters in a `String`.
  //
  /// The only purpose of this type is to provide a wrapper around `CountableClosedRange`
  /// that can be initialized both with a range and an **integer literal**.
  struct TextRange: ExpressibleByIntegerLiteral {
  
      let range: CountableClosedRange&lt;Int&gt;
  
      var lowerBound: Int {
          return range.lowerBound
      }
  
      var upperBound: Int {
          return range.upperBound
      }
  
      init(_ range: CountableClosedRange&lt;Int&gt;) {
          self.range = range
      }
  
      // This initializer adds the protocol conformance:
      init(integerLiteral value: Int) {
          self.range = value...value
      }
  
  }
  </code></pre>
  
  <p>With this definition I can write:</p>
  
  <pre><code>let x: TextRange = 5    // x is now a `TextRange`
  </code></pre>
  
  <p>However, </p>
  
  <pre><code>let x = 5               // x is now an `Int`
  </code></pre>
  
  <p>still infers x to be an <code>Int</code>. So far, so good.</p>
  
  <hr>
  
  <h2>Overloading the <code>...</code> operator</h2>
  
  <p>Now I also want to be able to create a <code>TextRange</code> with the closed range operator <code>...</code> like this:</p>
  
  <pre><code>let y: TextRange = 5...10
  </code></pre>
  
  <p>so I overload the <code>...</code> operator in an extension for <code>TextRange</code>s:</p>
  
  <pre><code>extension TextRange {
  
      /// Given two text ranges, this operator creates a new text range that incorporates
      /// the integers within the operand ranges as well as all integers between the operand ranges.
      ///
      /// - Parameters:
      ///   - lowerRange: A text range whose lower bound is smaller than the lower bound of `upperRange`.
      ///   - upperRange: A text range whose lower bound is greater than the lower bound of `lowerRange`.
      /// - Returns: A `TextRange` from the first operand's lower bound to the second operand's upper bound.
      static func ...(lowerRange: TextRange, upperRange: TextRange) -&gt; TextRange {
  
          let lowerBound = lowerRange.lowerBound
          let upperBound = max(lowerRange.upperBound, upperRange.upperBound)
  
          assert(lowerBound &lt;= upperBound, "Cannot create a TextRange because lowerBound &gt; upperBound.")
  
          return TextRange(lowerBound...upperBound)
      }
  
  }
  </code></pre>
  
  <p>And this is where I get into trouble. <em>(What a surprise: The trouble begins with operator overloading!</em> <em>)</em></p>
  
  <hr>
  
  <h2>Trouble</h2>
  
  <p>For a variable of <code>TextRange</code> type this operator works as expected but when I omit the type annotation the variable is still instantiated as a <code>TextRange</code>:</p>
  
  <pre><code>let y = 5...10           // y is now a `TextRange`
  </code></pre>
  
  <p><strong>That shouldn't be</strong> because:</p>
  
  <ul>
  <li><p>If no type is specified for a variable, </p>
  
  <blockquote>
    <p>the default inferred type of an integer literal is the Swift standard library type Int.</p>
  </blockquote>
  
  <p>(see <a href="https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html" rel="nofollow noreferrer"><em>Integer Literals</em> in <em>The Swift Programming Language</em></a>)</p>
  
  <p>Thus, I would expect <code>5</code> and <code>10</code> to be inferred to <code>Int</code>, not <code>TextRange</code>.</p></li>
  <li><p>The overload of the <code>...</code> operator is only implemented for two operands of <code>TextRange</code> type. Thus, <code>x...y</code> should still use the original Swift implementation of <code>...</code> if <code>x</code> and <code>y</code> are both <code>Int</code>s.</p></li>
  </ul>
  
  <p>So why does the compiler "decide" that it should now use the overloaded operator by default for ranges between two integer literals and interpret <code>x</code> and <code>y</code> in the pattern <code>x...y</code> as <code>TextRange</code>s?</p>
  
  <h3>Is there a way to tell the compiler which operator should be used by default in case the type of the two operands is not specified?</h3>