Description
Previous ID | SR-7868 |
Radar | rdar://problem/40775762 |
Original Reporter | @Lukasa |
Type | Bug |
Environment
Swift 4.2 beta
Additional Detail from JIRA
Votes | 0 |
Component/s | Foundation, libdispatch |
Labels | Bug |
Assignee | None |
Priority | Medium |
md5: 7f82935997669109761a47ee765077b8
Issue Description:
While attempting to write a protocol for both Data
and DispatchData
that covers their shared `enumerateBytes` method, I discovered that it is not really possible to do that. Consider the following example program:
import struct Foundation.Data
import struct Dispatch.DispatchData
protocol ByteEnumerator: Collection {
func enumerateBytes(block: (UnsafeBufferPointer<UInt8>, Self.Index, inout Bool) -> Void)
}
extension Data: ByteEnumerator { }
extension DispatchData: ByteEnumerator { }
This does not compile, because Data
has no label on its block:
test.swift:8:1: error: method 'enumerateBytes' has different argument labels from those required by protocol 'ByteEnumerator' ('enumerateBytes(block:)')
extension Data: ByteEnumerator { }
^
Foundation.Data:40:17: note: 'enumerateBytes' declared here
public func enumerateBytes(_ block: (UnsafeBufferPointer<UInt8>, Data.Index, inout Bool) -> Void)
^
test.swift:5:10: note: requirement 'enumerateBytes(block:)' declared here
func enumerateBytes(block: (UnsafeBufferPointer<UInt8>, Self.Index, inout Bool) -> Void)
If you try to suppress the label by changing the protocol method from func enumerateBytes(block: (UnsafeBufferPointer<UInt8>, Self.Index, inout Bool) -> Void)
to func enumerateBytes(_ block: (UnsafeBufferPointer<UInt8>, Self.Index, inout Bool) -> Void)
, this will again fail to compile, this time because of DispatchData
:
test.swift:9:1: error: method 'enumerateBytes(block:)' has different argument labels from those required by protocol 'ByteEnumerator' ('enumerateBytes')
extension DispatchData: ByteEnumerator { }
^
Dispatch.DispatchData:19:17: note: 'enumerateBytes(block:)' declared here
public func enumerateBytes(block: (UnsafeBufferPointer<UInt8>, Int, inout Bool) -> Void)
^
test.swift:5:10: note: requirement 'enumerateBytes' declared here
func enumerateBytes(_ block: (UnsafeBufferPointer<UInt8>, Self.Index, inout Bool) -> Void)
Given that these two data types can be bridged on Darwin, but not Linux, this inconsistency should probably be remedied.
(As a post-script, a tempting approach to bridge over this would be for my protocol to provide a default implementation for one case in terms of the other. However, because of the tail-closure syntax, doing this would cause an enormous number of compile errors.)