Swift 1.2b1: Bound type parameters receive priority over concrete types in overload selection

Originator:rix.rob
Number:rdar://19918050 Date Originated:22-Feb-2015 11:34 PM
Status:Open Resolved:
Product:Developer Tools Product Version:Xcode-Beta (6D520o)
Classification:Other Bug Reproducible:Always
 
Summary:
Given free and static functions (on S<T>) f with overloads (() -> T) -> S<T> and (() -> Bool) -> S<()>, applying the free function to { true } selects the S<()> overload, while static functions on S<T> select S<Bool>.

This appears to be because <T> bound in the type has priority over the concrete Bool overload: static functions on an unrelated type which does not bind the type parameter behave identically to free functions.


Steps to Reproduce:
1. Compile & run this:

struct S<T>: Printable, DebugPrintable {
	init(v: T) { self.v = v }
	let v: T
	static func f(f: () -> Bool) -> S<()> { return S<()>(v: ()) }
	static func f(f: () -> T) -> S<T> { return S(v: f()) }
	var description: String { return toString(v) }
	var debugDescription: String { return toDebugString(v) }
}
struct U {
	static func f(f: () -> Bool) -> S<()> { return S<()>(v: ()) }
	static func f<T>(f: () -> T) -> S<T> { return S(v: f()) }
}
func f(f: () -> Bool) -> S<()> { return S(v: ()) }
func f<T>(f: () -> T) -> S<T> { return S(v: f()) }

let a = f { true }
let b = f { 1 }
let c = S.f { true }
let d = S.f { 1 }
let e = U.f { true }
let g = U.f { 1 }
println(a.description)
println(b.description)
println(c.description)
println(d.description)
println(e.description)
println(g.description)


Expected Results:
I expected the output to be the same for all three sets, i.e.:
()
1
()
1
()
1


Actual Results:
The function on S selects the generic overload despite the availability of a concrete one, resulting in:
()
1
true
1
()
1


Regression:
This is not a regression since Swift 1.1; it was similarly surprising.


Notes:
One cannot realistically work around this issue by binding the type parameter in f, as callers then have to specify the type explicitly, i.e. let d = S<Int>.f { 1 }, which defeats the purpose of the inferencing altogether.

This therefore necessitates the use of free functions where I would otherwise prefer to use a static function.

Comments


Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!