Extensions of Swift classes and structs behave differently

Originator:ilyapuchka
Number:rdar://23314307 Date Originated:29.10.15
Status:Open Resolved:
Product:Developer tools Product Version:
Classification: Reproducible:
 
Summary:
Methods added in extensions to struct with generic type result in ambiguous methods if you provide two extensions with different generic type constraints using "where".
In same case for class or for protocol with type alias there is no ambiguity.

Steps to Reproduce:
1. Define some protocols:
protocol ProtocolA {}
protocol ProtocolB: ProtocolA {}
protocol ProtocolC {
    fun act()
}

2. Define struct with generic type:
struct StructA: ProtocolA {}
struct StructB: ProtocolB {}

struct StructC<T: ProtocolA>: ProtocolC {}

3. Define extensions with different generic type constraints:

extension StructC {
    func act() {
        print("general")
    }
}

extension StructC where T: ProtocolB {
    func act() {
        print("special")
    }
}

4. Create instance of generic struct with different generic types and call method defined in extension:

let structCA = StructC<StructA>()
let structCB = StructC<StructB>()

structCA.act() //should print "general"
structCB.act() //should print "special"



Expected Results:
Code compiles and more specialised extension is chosen for more specialised type. Output should look like this:
"general"
"special"


Actual Results:
Result: last line (structCB.act()) results in compiler  error: "Ambigous use of 'act()'"
Compiler adds method 'act()' from both extensions on 'structCB'.

If StructC is defined as class, not a struct than it works as expected without ambiguity

Version:
Xcode 7.1(7B91b)

Comments

Gist that demonstrates issue: https://gist.github.com/ilyapuchka/89f81090c09d361596b6

By ilyapuchka at Oct. 29, 2015, 3:31 p.m. (reply...)

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!