Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SR-8305] Swift 4.1.50 incompatibility with .map(Data.init) on String.UTF8View #3663

Open
keith opened this issue Jul 18, 2018 · 5 comments
Open

Comments

@keith
Copy link
Contributor

keith commented Jul 18, 2018

Previous ID SR-8305
Radar rdar://problem/42296476
Original Reporter @keith
Type Bug
Environment

Xcode 9.4.1 and Xcode 10 beta 4
Swift 4.1

Additional Detail from JIRA
Votes 0
Component/s Foundation
Labels Bug, SourceCompatibility
Assignee None
Priority Medium

md5: 138ae961b16b353bf87d2faead4c1242

is duplicated by:

  • SR-8333 Compiler fails to disambiguate .map(Data.init) in Xcode 10 Beta 4

Issue Description:

In Xcode 9.4.1 with Swift 4.1.2 this compiles:

import Foundation

let string: String.UTF8View? = "Hi".utf8
_ = string.map(Data.init)

With Xcode 10 beta 4 and Swift 4.1.50 it produces this error:

foo.swift:4:16: error: ambiguous use of 'init'
_ = string.map(Data.init)
               ^
Foundation.Data:29:12: note: found this candidate
    public init<S>(_ elements: S) where S : Sequence, S.Element == UInt8
           ^
Foundation.Data:30:12: note: found this candidate
    public init<S>(bytes elements: S) where S : Sequence, S.Element == UInt8
           ^

Changing the code to this fixes it:

import Foundation

let string: String.UTF8View? = "Hi".utf8
_ = string.map { Data($0) }
@belkadan
Copy link

Hm. I'm not sure anything's going to change here; strictly maintaining source compatibility would mean never adding new overloads. cc @phausler, @rudkx, @airspeedswift

@phausler
Copy link
Member

`init(bytes: Sequence)` and `init(_ elements: Sequence)` are not overloads in that they have two different names. It seems linguistically that fetching the init function should have a more qualified name: e.g. via argument labels as they are part of the signature fo the function.

Consider the following translation to objc:

+ (instancetype)dataWithSequence:(Sequence<UInt8> *)sequence;
// and the other method
+ (instancetype)dataWithBytes:(Sequence<UInt8> *)sequence;
// so fetching the IMP to pass to a mapping function would use two distinct selectors
[Data methodForSelector:@selector(dataWithSequence)];
[Data methodForSelector:@selector(dataWithBytes)];

So in the end it seems like there ought to be a way to specify

init(:)

versus

init(bytes:)

imho.

@phausler
Copy link
Member

Also it might be suggested to use

"Hi".data(using:.utf8)

instead anyhow to convert to data from a String.

@belkadan
Copy link

That's not how Swift works. "Overloads" means the same base name, differentiating first by argument names and then by types. That's important for default arguments.

(You certainly can write string.map(Data.init(_:)), and I kind of thing the current syntax shouldn't be legal myself, but it is. Still, I don't think that should stop us from adding new overloads, especially new initializers!)

@keith
Copy link
Contributor Author

keith commented Jul 18, 2018

Definitely not a huge deal if this isn't source compatible, but I wanted to flag it in case that wasn't desired.

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
@shahmishal shahmishal transferred this issue from apple/swift May 5, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants