Description
Description
Working on a Swift package using C++ interoperability I am facing an issue handling string conversion between Swift String
and C++ std::string
.
My C++ proxy class with exception handling looks like this:
struct CxxError {
private:
int _code;
std::string _message;
public:
int getCode() const SWIFT_COMPUTED_PROPERTY { return _code; }
std::string getMessage() const SWIFT_COMPUTED_PROPERTY { return _message; }
CxxError() : _code(0), _message(std::string()) {}
CxxError(const Error& error) : _code(error.code()), _message(error.what()) {}
};
#pragma mark -
class CxxProxy {
public:
CxxProxy(const std::string& name, Error& error);
}
Accordingly a Swift wrapper class handling errors with Swift exceptions looks like:
public class SwiftWrapper {
public let url: URL
private var cxxProxy: CxxProxy
struct Error: Swift.Error {
let message: String
init(message: std.string) {
self.message = String(message)
}
}
public init(url: URL) throws {
var error = CxxError()
let cxxProxy = CxxProxy(std.string(url.path), &error)
guard error.code == 0 else {
throw Error(message: error.message)
}
self.url = url
self.cxxProxy = cxxProxy
}
While targeting iOS, macOS and Linux this code compiles and runs without any issues, on MacCatalyst the compiler reports two string conversion related issues:
error: no exact matches in call to initializer
self.message = String(message)
^
Swift.String:4:23: note: candidate requires that 'std.string' (aka 'std.__1.basic_string<CChar, char_traits<CChar>, allocator<CChar>>') conform to 'LosslessStringConvertible' (requirement specified as 'T' : 'LosslessStringConvertible')
@inlinable public init<T>(_ value: T) where T : LosslessStringConvertible
^
Swift.String:2:12: note: candidate requires that 'std.string' (aka 'std.__1.basic_string<CChar, char_traits<CChar>, allocator<CChar>>') conform to 'BinaryInteger' (requirement specified as 'T' : 'BinaryInteger')
public init<T>(_ value: T, radix: Int = 10, uppercase: Bool = false) where T : BinaryInteger
^
Swift.String:4:12: note: candidate requires that 'std.string' (aka 'std.__1.basic_string<CChar, char_traits<CChar>, allocator<CChar>>') conform to 'Sequence' (requirement specified as 'S' : 'Sequence')
public init<S>(_ characters: S) where S : Sequence, S.Element == Character
^
Swift.RangeReplaceableCollection:3:23: note: candidate requires that 'std.string' (aka 'std.__1.basic_string<CChar, char_traits<CChar>, allocator<CChar>>') conform to 'Sequence' (requirement specified as 'S' : 'Sequence')
@inlinable public init<S>(_ elements: S) where S : Sequence, Self.Element == S.Element
^
Swift.String:2:12: note: incorrect labels for candidate (have: '(_:)', expected: '(describing:)')
public init<Subject>(describing instance: Subject)
^
Swift.String:6:12: note: incorrect labels for candidate (have: '(_:)', expected: '(reflecting:)')
public init<Subject>(reflecting subject: Subject)
^
error: no exact matches in call to initializer
let imageProxy = CxxProxy(std.string(url.path), &error)
^
__ObjC.std:1155:20: note: candidate expects value of type 'std.__1.basic_string<CChar, char_traits<CChar>, allocator<CChar>>.allocator_type' (aka 'std.__1.allocator<CChar>') for parameter #1 (got 'String')
public init(_ __a: std.__1.basic_string<CChar, char_traits<CChar>, allocator<CChar>>.allocator_type)
^
__ObjC.std:1162:20: note: candidate expects value of type 'std.initializer_list<CChar>' for parameter #1 (got 'String')
public init(_ __il: std.initializer_list<CChar>)
^
Reproduction
Use above code to reproduce in a sample project.
Alternatively use my original SwiftExiv2 package to compile in Xcode with Mac Catalyst as target.
Expected behavior
Mac Catalyst should compile above code the same way successfully as it does with iOS, macOS and Linux as target.
Environment
Swift: swift-driver version: 1.115 Apple Swift version 6.0 (swiftlang-6.0.0.9.10 clang-1600.0.26.2) Target: arm64-apple-macosx15.0
Xcode: Xcode 16.0 Build version 16A242d
Deployment target: Mac Catalyst
Additional information
No response