Generic protocol conformance bug


(Ryan Lovelett) #1

I think I've discovered a few bugs/inconsistencies with generic protocol
conformance. I'm mostly concerned with if these have been seen/reported
before. I'm pretty sure they are all bugs but I could be wrong (I've
been wrong before, it _will_ happen again :grinning:).

All of the (possible?) bugs can be seen in this Gist [1]. I'll provide
some commentary on what I think is the bug/inconsistency.

`example_1.swift`: I expected this not to compile. The `Optional`
extension does not conform to the protocol. It returns a `String` when I
would have expected the returned type to be _required_ to have been
`Wrapped` (e.g., `Int`).

`example_2.swift`: I expected this also not compile. The function
signature is wrong. The protocol requires a function `bar(qux:)` but
allows the signature `bar(q:)` to conform.

`example_3.swift`: This one is probably the only "correct" one. This one
fails to compile with the error I would have expected from
`example_2.swift`.

All of this is from the "Trunk Development (master)" dated May 9th
currently available on Swift.org [2].

# example_1.swift

public protocol Foo {
  associatedtype Bar = Self
  func bar(qux: String) -> Bar
}

extension Int: Foo {
  public func bar(qux: String) -> Int {
    return self
  }
}

extension Optional where Wrapped: Foo, Wrapped == Wrapped.Bar {
  public func bar(qux: String) -> String {
    return #function
  }
}

let result = 3.bar(qux: "metasyntactic")
print(result) // 3

let optional = Optional.some(3).bar(qux: "metasyntactic")
print(optional) // bar(qux:)

# example_2.swift

public protocol Foo {
  associatedtype Bar = Self
  func bar(qux: String) -> Bar
}

extension Int: Foo {
  public func bar(qux: String) -> Int {
    return self
  }
}

extension Optional where Wrapped: Foo, Wrapped == Wrapped.Bar {
  public func bar(q: String) -> Wrapped? {
    return self
  }
}

let result = 3.bar(qux: "metasyntactic")
print(result) // 3

let optional = Optional.some(3).bar(q: "metasyntactic")
print(optional) // Optional(3)

# example_3.swift

public protocol Foo {
  associatedtype Bar = Self
  func bar(qux: String) -> Bar
}

extension Int: Foo {
  public func bar(q: String) -> Int {
    return self
  }
}

extension Optional where Wrapped: Foo, Wrapped == Wrapped.Bar {
  public func bar(q: String) -> Wrapped? {
    return self
  }
}

let result = 3.bar(q: "metasyntactic")
print(result)

let optional = Optional.some(3).bar(q: "metasyntactic")
print(optional)

[1] https://gist.github.com/RLovelett/8b7c5eb8976554ca359707445a9c86f0
[2] https://swift.org/download/#snapshots


(Ryan Lovelett) #2

Ugh. Can you un-send an email. I was wrong. See it happened AGAIN. :joy:

···

On Mon, May 23, 2016, at 12:16 PM, Ryan Lovelett via swift-dev wrote:

I think I've discovered a few bugs/inconsistencies with generic protocol
conformance. I'm mostly concerned with if these have been seen/reported
before. I'm pretty sure they are all bugs but I could be wrong (I've
been wrong before, it _will_ happen again :grinning:).

All of the (possible?) bugs can be seen in this Gist [1]. I'll provide
some commentary on what I think is the bug/inconsistency.

`example_1.swift`: I expected this not to compile. The `Optional`
extension does not conform to the protocol. It returns a `String` when I
would have expected the returned type to be _required_ to have been
`Wrapped` (e.g., `Int`).

`example_2.swift`: I expected this also not compile. The function
signature is wrong. The protocol requires a function `bar(qux:)` but
allows the signature `bar(q:)` to conform.

`example_3.swift`: This one is probably the only "correct" one. This one
fails to compile with the error I would have expected from
`example_2.swift`.

All of this is from the "Trunk Development (master)" dated May 9th
currently available on Swift.org [2].

# example_1.swift

public protocol Foo {
  associatedtype Bar = Self
  func bar(qux: String) -> Bar
}

extension Int: Foo {
  public func bar(qux: String) -> Int {
    return self
  }
}

extension Optional where Wrapped: Foo, Wrapped == Wrapped.Bar {
  public func bar(qux: String) -> String {
    return #function
  }
}

let result = 3.bar(qux: "metasyntactic")
print(result) // 3

let optional = Optional.some(3).bar(qux: "metasyntactic")
print(optional) // bar(qux:)

# example_2.swift

public protocol Foo {
  associatedtype Bar = Self
  func bar(qux: String) -> Bar
}

extension Int: Foo {
  public func bar(qux: String) -> Int {
    return self
  }
}

extension Optional where Wrapped: Foo, Wrapped == Wrapped.Bar {
  public func bar(q: String) -> Wrapped? {
    return self
  }
}

let result = 3.bar(qux: "metasyntactic")
print(result) // 3

let optional = Optional.some(3).bar(q: "metasyntactic")
print(optional) // Optional(3)

# example_3.swift

public protocol Foo {
  associatedtype Bar = Self
  func bar(qux: String) -> Bar
}

extension Int: Foo {
  public func bar(q: String) -> Int {
    return self
  }
}

extension Optional where Wrapped: Foo, Wrapped == Wrapped.Bar {
  public func bar(q: String) -> Wrapped? {
    return self
  }
}

let result = 3.bar(q: "metasyntactic")
print(result)

let optional = Optional.some(3).bar(q: "metasyntactic")
print(optional)

[1] https://gist.github.com/RLovelett/8b7c5eb8976554ca359707445a9c86f0
[2] https://swift.org/download/#snapshots
_______________________________________________
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev