Skip to content

[cxx-interop, maccatalyst] CxxOptional does not work on Catalyst as it does on iOS, macOS and Linux #76999

Open
@wmanth

Description

@wmanth

Description

Working on a Swift package using C++ interoperability I am facing an issue handling optional values when compiling it with Mac Catalyst as target.

While principally it should be possible to use Swift Optionals in C++, the documentation also states regarding Mixing Swift and C++ Using Swift Package Manager:

Swift Package Manager does not yet provide support for using Swift APIs in C++.

Hence, I use a C++ proxy class that works around this limitation by returning a std::optional from C++ to Swift instead:

public:
    std::optional<DateTime> getDateTimeOriginal() const;

Accordingly, a Swift wrapper offers a computed getter with Optional return value:

    public var dateTimeOriginal: DateTime? {
        get { imageProxy.getDateTimeOriginal().value }

While targeting iOS, macOS and Linux this code compiles and runs without any issues, on MacCatalyst the compiler reports:

error: value of type 'std.__1.optional<DateTime>' has no member 'value'
        get { imageProxy.getDateTimeOriginal().value }
              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^~~~~

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

The getter value together with hasValue are exposed by the Cxx module most likely by calling their C++ stdlib std::optional pendants has_value() and value():

extension CxxOptional {

    /// Creates an instance initialized with `nil`.
    public init(nilLiteral: ())

    @inlinable public var hasValue: Bool { get }

    @inlinable public var value: Self.Wrapped? { get }
}

In fact, above Swift getter could also be written as:

        get {
            let dateTime = imageProxy.getDateTimeOriginal()
            return dateTime.hasValue ? dateTime.value : nil
        }

This works for iOS, macOS and Linux as well.

Considering #73409 has been closed I would assume the CxxOptional extension works for Mac Catalyst as well.

Trying to not use the extension, I was able to silence the compiler using:

        get {
            let dateTime = imageProxy.getDateTimeOriginal()
            return dateTime.has_value() ? dateTime.pointee : nil
        }

Though this code compiles for Mac Catalyst without issues, I was not able to test whether it runs due to another issue with Mac Catalyst C++ interoperability #77000 .

Metadata

Metadata

Assignees

No one assigned

    Labels

    CxxArea → standard library: The `Cxx` moduleMac CatalystPlatform: Mac CatalystbugA deviation from expected or documented behavior. Also: expected but undesirable behavior.c++ interopFeature: Interoperability with C++c++ to swiftFeature → c++ interop: c++ to swiftswift 6.0unexpected errorBug: Unexpected error

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions