swiftlang / swift

The Swift Programming Language
https://swift.org
Apache License 2.0
67.53k stars 10.35k forks source link

Interop: Cannot return `swift::Optional<swift::String>` from C++ function #76024

Open ADKaster opened 2 months ago

ADKaster commented 2 months ago

Description

Is it intended that the bound types swift::Optional and swift::String cannot be used to return swift types to swift?

Attempting to do so results in the swift::Optional<T> for some T being replaced with Never

/Users/andrew/Source/test/swift-return-swift-type/exe/Helper.swift:5:11: error: 'getValue()' is unavailable: return type is unavailable in Swift
3 | func printThings()
4 | {
5 |     print(getValue())
  |           `- error: 'getValue()' is unavailable: return type is unavailable in Swift
6 |     print(getString())
7 | }

exe.getValue:2:13: note: 'getValue()' has been explicitly marked unavailable here
1 | @available(*, unavailable, message: "return type is unavailable in Swift")
2 | public func getValue() -> Never
  |             `- note: 'getValue()' has been explicitly marked unavailable here

/Users/andrew/Source/test/swift-return-swift-type/exe/Helper.swift:6:11: error: 'getString()' is unavailable: return type is unavailable in Swift
4 | {
5 |     print(getValue())
6 |     print(getString())
  |           `- error: 'getString()' is unavailable: return type is unavailable in Swift
7 | }
8 | 

exe.getString:2:13: note: 'getString()' has been explicitly marked unavailable here
1 | @available(*, unavailable, message: "return type is unavailable in Swift")
2 | public func getString() -> Never
  |             `- note: 'getString()' has been explicitly marked unavailable here

Reproduction

This test case requires a few files, which I have uploaded here:

https://github.com/ADKaster/swift-return-swift-type

The results can be reproduced with

cmake -B build -GNinja
cmake --build build
# or ninja -C build

In the example, a few things are happening:

Helper.h

#pragma once

#include "Color.h"
#include "shlib-Swift.h"

swift::Optional<int> getValue() noexcept;
swift::Optional<swift::String> getString() noexcept;

Helper.cpp

#include "Helper.h"

swift::Optional<int> getValue() noexcept { return swift::Optional<int>::some(42); }
swift::Optional<swift::String> getString() noexcept { return swift::Optional<swift::String>::none(); }

Helper.swift

import exe

func printThings()
{
    print(getValue())
    print(getString())
}

Expected behavior

The program should compile successfully and print "42\nnone\n"

Environment

swift-driver version: 1.113 Apple Swift version 6.0 (swiftlang-6.0.0.7.6 clang-1600.0.24.1) Target: arm64-apple-macosx14.0

Additional information

No response

Xazax-hun commented 4 weeks ago

I will take a look at this.