How does the Swift compiler determine which method or operator to call given a 
set of overloads at a given call site? This question may conflate two issues: 
method overloads and operator overloads, but it seems at least superficially 
that they are related. Somehow they end up using different rules as I will 
demonstrate shortly.

<code>
class A{
}

class B: A {
}

func +(a:A, b:A){
  print("+1")
}

func +(a:A, b:B){
  print("+2")
}

func +(a:B, b:A){
  print("+3")
}

/*
func +(a:B, b:B){
  print("+4")
}
*/

A() + A() // prints +1
A() + B() // prints +1
B() + A() // prints +1
// B() + B() // will come back to this

func f(a: A, b: A){
  print("f1")
}

func f(a: B, b: A){
  print("f2")
}

func f(a: A, b: B){
  print("f3")
}

/*
func f(a: B, b: B){
  print("f4")
}
*/

f(A(), b: A()) // prints f1
f(B(), b: A()) // prints f2
f(A(), b: B()) // prints f3
// f(B(), b: B()) // will come back to this
</code>

The output from the various invocations of f() make sense. It seems that Swift 
uses similar overload resolution rules as Java where the 'most specific method' 
is chosen given a set of methods whose parameters are part of the same class 
hierarchy.

Given the code as-is, the outputs from the operator overloads all seem to call 
the first operator defined. The order of definition doesn't matter, if +(A, A) 
is put last it will still be called by all three invocations of +. Already this 
doesn't make sense to me. Why isn't +(A, B) called for the expression A() + B()?
Something strange happens when the function +(B, B) is uncommented out. All of 
a sudden the overloads work just like they did in the regular function 
definition case.

The full code is:

<code>
func +(a:A, b:A){
  print("+1")
}

func +(a:A, b:B){
  print("+2")
}

func +(a:B, b:A){
  print("+3")
}

func +(a:B, b:B){
  print("+4")
}

A() + A() // prints +1
A() + B() // prints +2
B() + A() // prints +3
B() + B() // prints +4
</code>

Without the definition of +(B, B) the expression B() + B() is an error because 
it is ambiguous whether to choose +(A, B) or +(B, A). I am fine with that 
behavior. But why do A()+B() and B()+A() suddenly refer to the +2 and +3 
operators respectively?

The regular function case does not behave this way. Given the 3 uncommented 
defintions of f as above the output is as expected, f1, f2, f3 in order. When 
the definition of f(B, B) is uncommented the expression f(B(), B()) works as 
expected and prints f4. The other expressions are unaffected.

--
_______________________________________________
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev

Reply via email to