swiftlang / swift

The Swift Programming Language
https://swift.org
Apache License 2.0
67.58k stars 10.36k forks source link

[SR-7710] Prototype function implementation that should match won't when using where clauses #50250

Open swift-ci opened 6 years ago

swift-ci commented 6 years ago
Previous ID SR-7710
Radar None
Original Reporter vincent (JIRA User)
Type Bug
Environment macOS High Sierra 10.13.4 (17E202) Apple Swift version 4.1 (swiftlang-902.0.48 clang-902.0.37.1) Target: x86_64-apple-darwin17.5.0
Additional Detail from JIRA | | | |------------------|-----------------| |Votes | 0 | |Component/s | Compiler | |Labels | Bug | |Assignee | None | |Priority | Medium | md5: 45bbd4a261e2e582a2992f418f630d4c

Issue Description:

In the code below, I get a compilation error telling me that AT2 doesn't conform to P3 even though it does. It compiles properly if I remove any of the where clauses ("where AT3.AT2 == Self" or "where T1.AT1 == AT3").

import Foundation

protocol P1 {
    associatedtype AT1: P2
}

protocol P2 {
    associatedtype AT2: P3
}

protocol P3 {
    associatedtype AT3: P2 where AT3.AT2 == Self
    func foo<T1: P1>() -> C2<T1> where T1.AT1 == AT3
}

class C1: P2 {
    class AT2: P3 {
        typealias AT3 = C1

        func foo<T1: P1>() -> C2<T1> where T1.AT1 == AT3 {
            fatalError()
        }
    }
}

class C2<T2: P1> {}

Error:

bug.swift:17:11: error: type 'C1.AT2' does not conform to protocol 'P3'
    class AT2: P3 {
          ^
bug.swift:20:14: note: candidate has non-matching type '<T1> () -> C2<T1>'
        func foo<T1: P1>() -> C2<T1> where T1.AT1 == AT3 {
             ^
bug.swift:13:10: note: protocol requires function 'foo()' with type '<T1> () -> C2<T1>'; do you want to add a stub?
    func foo<T1: P1>() -> C2<T1> where T1.AT1 == AT3
belkadan commented 6 years ago

cc @huonw

d4adc30e-df4b-4925-bfeb-69e631c0be69 commented 6 years ago

I have a suspicion that I've seen a JIRA like this before, but I can't find it right now, so maybe not.

The generic signatures:

sr7710.(file).P3.foo()@sr7710.swift:11:10
Generic signature: <Self, T1 where T1 : P1, Self.AT3 == T1.AT1>
Canonical generic signature: <τ_0_0, τ_1_0 where τ_1_0 : P1, τ_0_0.AT3 == τ_1_0.AT1>

sr7710.(file).C1.AT2.foo()@sr7710.swift:18:14
Generic signature: <T1 where T1 : P1, T1.AT1 == C1.AT2.AT3>
Canonical generic signature: <τ_0_0 where τ_0_0 : P1, τ_0_0.AT1 == C1>
d4adc30e-df4b-4925-bfeb-69e631c0be69 commented 6 years ago

Oh, and I remove the where on the associated type, the protocol's foo's signature looks like:

sr7710.(file).P3.foo()@sr7710.swift:11:10
Generic signature: <Self, T1 where Self : P3, T1 : P1, Self.AT3 == T1.AT1>
Canonical generic signature: <τ_0_0, τ_1_0 where τ_0_0 : P3, τ_1_0 : P1, τ_0_0.AT3 == τ_1_0.AT1>

I.e. there's a Self : P3 requirement that the broken one is missing.