String(cString:, encoding:) with non 1-byte encodings should trigger a warning somewhere

Background

This comes from NSString via the Foundation overlay. The standard library has alternatives with generic constraints which ensure the byte-width is appropriate for encoding here.

There is a lot of overlap and redundancy between the initializers added in the Foundation overlay and those directly from the standard library. We should really clean this up for Swift 5 (related thread). CC @lancep, @itaiferber.

@benjamin.g, could you file a bug at bugs.swift.org to help track this?

Potential solutions / alternatives

For the following String init:

init?(cString: UnsafePointer<CChar>, encoding enc: String.Encoding)

Using UnsafePointer<CChar> as the argument type is misleading. At the very least, if this is meant as a lowest-level interface, should it be UnsafeRawPointer? CC @Andrew_Trick for thoughts.

For:

init?<S : Sequence where S.Iterator.Element == UInt8>(bytes: S, encoding: String.Encoding)

The intent is to create a String from raw bytes, i.e. data. Should this initializer be considered redundant with an initializer taking Data and/or with init(decoding:as:)? The latter has a generic constraint that the element type is equivalent to the encoding's code unit type.

edit:

CC @johannesweiss. It might make sense to tackle initializer cleanup as part of a move to an early-validation model. We also might want to consider how we want to fit in performance-flags testing as well.

2 Likes