swiftlang / swift

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

[cxx-interop] Capturing a `std::function` with arguments in a Swift closure causes a compiler crash #76143

Open mrousavy opened 2 weeks ago

mrousavy commented 2 weeks ago

Description

I have a C++ std::function<void(double)> (a std::function with arguments) which I want to wrap in a nice Swift closure ((Double) -> Void), to be able to call it later.

The C++ std::function has some captured state, in my case a shared_ptr, but it is still copyable:

using Func_void_double = std::function<void(double)>;

void updateListener() {
  std::shared_ptr<int> someState;
  swiftSomething.setListener([someState](double num) -> void {
    std::cout << "Listener called: " << num << std::endl;
  });
}

My Swift property then wraps this std::function as a Swift closure:

public class Something {
  let callback: (Double) -> Void

  public func setListener(listener: Func_void_double) {
    // Wrap std::function as Swift closure, and assign to member value `self.callback`
    self.callback = { (num: Double) -> Void in {
      listener(num) // <-- call std::function
    }
  }
}

While this works with an std::function without arguments (std::function<void()>), it crashes the compiler when using a std::function with arguments (std::function<void(double)>)!

Reproduction

see code above

Stack dump

Global is external, but doesn't have external or weak linkage!
ptr @2
Global is external, but doesn't have external or weak linkage!
ptr @3
Please submit a bug report (https://swift.org/contributing/#reporting-bugs) and include the crash backtrace.
Stack dump:
0.  Program arguments: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift-frontend -frontend -c /Users/mrousavy/Projects/nitro/packages/react-native-nitro-image/nitrogen/generated/ios/swift/Car.swift /Users/mrousavy/Projects/nitro/packages/react-native-nitro-image/ios/HybridImage.swift /Users/mrousavy/Projects/nitro/packages/react-native-nitro-image/ios/HybridImageFactory.swift /Users/mrousavy/Projects/nitro/packages/react-native-nitro-image/nitrogen/generated/ios/swift/HybridImageFactorySpec.swift /Users/mrousavy/Projects/nitro/packages/react-native-nitro-image/nitrogen/generated/ios/swift/HybridImageFactorySpecCxx.swift /Users/mrousavy/Projects/nitro/packages/react-native-nitro-image/nitrogen/generated/ios/swift/HybridImageSpec.swift /Users/mrousavy/Projects/nitro/packages/react-native-nitro-image/nitrogen/generated/ios/swift/HybridImageSpecCxx.swift /Users/mrousavy/Projects/nitro/packages/react-native-nitro-image/ios/HybridSwiftKotlinTestObject.swift /Users/mrousavy/Projects/nitro/packages/react-native-nitro-image/nitrogen/generated/ios/swift/HybridSwiftKotlinTestObjectSpec.swift -primary-file /Users/mrousavy/Projects/nitro/packages/react-native-nitro-image/nitrogen/generated/ios/swift/HybridSwiftKotlinTestObjectSpecCxx.swift /Users/mrousavy/Projects/nitro/packages/react-native-nitro-image/nitrogen/generated/ios/swift/ImageFormat.swift /Users/mrousavy/Projects/nitro/packages/react-native-nitro-image/nitrogen/generated/ios/swift/ImageSize.swift /Users/mrousavy/Projects/nitro/packages/react-native-nitro-image/ios/NitroImageRegistry.swift /Users/mrousavy/Projects/nitro/packages/react-native-nitro-image/nitrogen/generated/ios/swift/OldEnum.swift /Users/mrousavy/Projects/nitro/packages/react-native-nitro-image/nitrogen/generated/ios/swift/Person.swift /Users/mrousavy/Projects/nitro/packages/react-native-nitro-image/nitrogen/generated/ios/swift/PixelFormat.swift /Users/mrousavy/Projects/nitro/packages/react-native-nitro-image/nitrogen/generated/ios/swift/Powertrain.swift -emit-dependencies-path /Users/mrousavy/Library/Developer/Xcode/DerivedData/NitroExample-grbugsgaxfdmulbldokvvxoydqpx/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/NitroImage.build/Objects-normal/arm64/HybridSwiftKotlinTestObjectSpecCxx.d -emit-const-values-path /Users/mrousavy/Library/Developer/Xcode/DerivedData/NitroExample-grbugsgaxfdmulbldokvvxoydqpx/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/NitroImage.build/Objects-normal/arm64/HybridSwiftKotlinTestObjectSpecCxx.swiftconstvalues -emit-reference-dependencies-path /Users/mrousavy/Library/Developer/Xcode/DerivedData/NitroExample-grbugsgaxfdmulbldokvvxoydqpx/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/NitroImage.build/Objects-normal/arm64/HybridSwiftKotlinTestObjectSpecCxx.swiftdeps -serialize-diagnostics-path /Users/mrousavy/Library/Developer/Xcode/DerivedData/NitroExample-grbugsgaxfdmulbldokvvxoydqpx/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/NitroImage.build/Objects-normal/arm64/HybridSwiftKotlinTestObjectSpecCxx.dia -target arm64-apple-ios13.4-simulator -Xllvm -aarch64-use-tbi -enable-objc-interop -cxx-interoperability-mode=default -sdk /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator17.5.sdk -I /Users/mrousavy/Library/Developer/Xcode/DerivedData/NitroExample-grbugsgaxfdmulbldokvvxoydqpx/Build/Products/Debug-iphonesimulator/NitroImage -I /Users/mrousavy/Library/Developer/Xcode/DerivedData/NitroExample-grbugsgaxfdmulbldokvvxoydqpx/Build/Products/Debug-iphonesimulator/NitroModules -F /Users/mrousavy/Library/Developer/Xcode/DerivedData/NitroExample-grbugsgaxfdmulbldokvvxoydqpx/Build/Products/Debug-iphonesimulator/NitroImage -F /Users/mrousavy/Projects/nitro/example/ios/Pods/hermes-engine/destroot/Library/Frameworks/universal -F /Users/mrousavy/Library/Developer/Xcode/DerivedData/NitroExample-grbugsgaxfdmulbldokvvxoydqpx/Build/Products/Debug-iphonesimulator/XCFrameworkIntermediates/hermes-engine/Pre-built -no-color-diagnostics -enable-testing -g -import-underlying-module -module-cache-path /Users/mrousavy/Library/Developer/Xcode/DerivedData/ModuleCache.noindex -swift-version 5 -enforce-exclusivity=checked -Onone -D DEBUG -D COCOAPODS -serialize-debugging-options -const-gather-protocols-file /Users/mrousavy/Library/Developer/Xcode/DerivedData/NitroExample-grbugsgaxfdmulbldokvvxoydqpx/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/NitroImage.build/Objects-normal/arm64/NitroImage_const_extract_protocols.json -enable-bare-slash-regex -empty-abi-descriptor -validate-clang-modules-once -clang-build-session-file /Users/mrousavy/Library/Developer/Xcode/DerivedData/ModuleCache.noindex/Session.modulevalidation -Xcc -working-directory -Xcc /Users/mrousavy/Projects/nitro/example/ios/Pods -resource-dir /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift -enable-anonymous-context-mangled-names -Xcc -fmodule-map-file=/Users/mrousavy/Library/Developer/Xcode/DerivedData/NitroExample-grbugsgaxfdmulbldokvvxoydqpx/Build/Products/Debug-iphonesimulator/NitroModules/NitroModules.modulemap -Xcc -fmodule-map-file=/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Public/DoubleConversion/DoubleConversion.modulemap -Xcc -fmodule-map-file=/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Public/RCTDeprecation/RCTDeprecation.modulemap -Xcc -fmodule-map-file=/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Public/RCTFabric/React-RCTFabric.modulemap -Xcc -fmodule-map-file=/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Public/RCTTypeSafety/RCTTypeSafety.modulemap -Xcc -fmodule-map-file=/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Public/React/React-Core.modulemap -Xcc -fmodule-map-file=/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Public/ReactCodegen/ReactCodegen.modulemap -Xcc -fmodule-map-file=/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Public/ReactCommon/ReactCommon.modulemap -Xcc -fmodule-map-file=/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Public/React_Fabric/React-Fabric.modulemap -Xcc -fmodule-map-file=/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Public/React_FabricComponents/React-FabricComponents.modulemap -Xcc -fmodule-map-file=/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Public/React_NativeModulesApple/React-NativeModulesApple.modulemap -Xcc -fmodule-map-file=/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Public/folly/RCT-Folly.modulemap -Xcc -fmodule-map-file=/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Public/glog/glog.modulemap -Xcc -fmodule-map-file=/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Public/jsi/React-jsi.modulemap -Xcc -fmodule-map-file=/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Public/jsinspector_modern/React-jsinspector.modulemap -Xcc -fmodule-map-file=/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Public/react_debug/React-debug.modulemap -Xcc -fmodule-map-file=/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Public/react_featureflags/React-featureflags.modulemap -Xcc -fmodule-map-file=/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Public/react_renderer_debug/React-rendererdebug.modulemap -Xcc -fmodule-map-file=/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Public/react_renderer_graphics/React-graphics.modulemap -Xcc -fmodule-map-file=/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Public/react_renderer_imagemanager/React-ImageManager.modulemap -Xcc -fmodule-map-file=/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Public/react_utils/React-utils.modulemap -Xcc -fmodule-map-file=/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Public/yoga/Yoga.modulemap -Xcc -fmodule-map-file=/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Public/NitroImage/NitroImage.modulemap -Xcc -std=c++20 -Xcc -ivfsstatcache -Xcc /Users/mrousavy/Library/Developer/Xcode/DerivedData/SDKStatCaches.noindex/iphonesimulator17.5-21F77-c098706a9f71eba4e76ae92ab367209a.sdkstatcache -Xcc -I/Users/mrousavy/Library/Developer/Xcode/DerivedData/NitroExample-grbugsgaxfdmulbldokvvxoydqpx/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/NitroImage.build/swift-overrides.hmap -Xcc -iquote -Xcc /Users/mrousavy/Library/Developer/Xcode/DerivedData/NitroExample-grbugsgaxfdmulbldokvvxoydqpx/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/NitroImage.build/NitroImage-generated-files.hmap -Xcc -I/Users/mrousavy/Library/Developer/Xcode/DerivedData/NitroExample-grbugsgaxfdmulbldokvvxoydqpx/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/NitroImage.build/NitroImage-own-target-headers.hmap -Xcc -I/Users/mrousavy/Library/Developer/Xcode/DerivedData/NitroExample-grbugsgaxfdmulbldokvvxoydqpx/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/NitroImage.build/NitroImage-all-non-framework-target-headers.hmap -Xcc -ivfsoverlay -Xcc /Users/mrousavy/Library/Developer/Xcode/DerivedData/NitroExample-grbugsgaxfdmulbldokvvxoydqpx/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/NitroImage.build/all-product-headers.yaml -Xcc -iquote -Xcc /Users/mrousavy/Library/Developer/Xcode/DerivedData/NitroExample-grbugsgaxfdmulbldokvvxoydqpx/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/NitroImage.build/NitroImage-project-headers.hmap -Xcc -I/Users/mrousavy/Library/Developer/Xcode/DerivedData/NitroExample-grbugsgaxfdmulbldokvvxoydqpx/Build/Products/Debug-iphonesimulator/NitroImage/include -Xcc -I/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Private -Xcc -I/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Private/NitroImage -Xcc -I/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Public -Xcc -I/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Public/DoubleConversion -Xcc -I/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Public/FBLazyVector -Xcc -I/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Public/RCT-Folly -Xcc -I/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Public/RCTRequired -Xcc -I/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Public/RCTTypeSafety -Xcc -I/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Public/React-Core -Xcc -I/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Public/React-Fabric -Xcc -I/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Public/React-FabricComponents -Xcc -I/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Public/React-FabricImage -Xcc -I/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Public/React-ImageManager -Xcc -I/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Public/React-NativeModulesApple -Xcc -I/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Public/React-RCTFabric -Xcc -I/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Public/React-RCTText -Xcc -I/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Public/React-callinvoker -Xcc -I/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Public/React-cxxreact -Xcc -I/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Public/React-debug -Xcc -I/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Public/React-featureflags -Xcc -I/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Public/React-graphics -Xcc -I/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Public/React-hermes -Xcc -I/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Public/React-jsi -Xcc -I/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Public/React-jsiexecutor -Xcc -I/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Public/React-jsinspector -Xcc -I/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Public/React-logger -Xcc -I/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Public/React-nativeconfig -Xcc -I/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Public/React-perflogger -Xcc -I/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Public/React-performancetimeline -Xcc -I/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Public/React-rendererconsistency -Xcc -I/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Public/React-rendererdebug -Xcc -I/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Public/React-runtimeexecutor -Xcc -I/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Public/React-runtimescheduler -Xcc -I/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Public/React-utils -Xcc -I/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Public/ReactCodegen -Xcc -I/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Public/ReactCommon -Xcc -I/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Public/Yoga -Xcc -I/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Public/boost -Xcc -I/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Public/fmt -Xcc -I/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Public/glog -Xcc -I/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Public/hermes-engine -Xcc -I/Users/mrousavy/Projects/nitro/example/ios/Pods/boost -Xcc -I/Users/mrousavy/Projects/nitro/example/ios/Pods/Headers/Private/Yoga -Xcc -I/Users/mrousavy/Library/Developer/Xcode/DerivedData/NitroExample-grbugsgaxfdmulbldokvvxoydqpx/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/NitroImage.build/DerivedSources-normal/arm64 -Xcc -I/Users/mrousavy/Library/Developer/Xcode/DerivedData/NitroExample-grbugsgaxfdmulbldokvvxoydqpx/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/NitroImage.build/DerivedSources/arm64 -Xcc -I/Users/mrousavy/Library/Developer/Xcode/DerivedData/NitroExample-grbugsgaxfdmulbldokvvxoydqpx/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/NitroImage.build/DerivedSources -Xcc -DPOD_CONFIGURATION_DEBUG=1 -Xcc -DDEBUG=1 -Xcc -DCOCOAPODS=1 -module-name NitroImage -frontend-parseable-output -disable-clang-spi -target-sdk-version 17.5 -target-sdk-name iphonesimulator17.5 -external-plugin-path /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator17.5.sdk/usr/lib/swift/host/plugins#/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator17.5.sdk/usr/bin/swift-plugin-server -external-plugin-path /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator17.5.sdk/usr/local/lib/swift/host/plugins#/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator17.5.sdk/usr/bin/swift-plugin-server -external-plugin-path /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/lib/swift/host/plugins#/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/swift-plugin-server -external-plugin-path /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/local/lib/swift/host/plugins#/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/swift-plugin-server -plugin-path /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/host/plugins -plugin-path /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/local/lib/swift/host/plugins -o /Users/mrousavy/Library/Developer/Xcode/DerivedData/NitroExample-grbugsgaxfdmulbldokvvxoydqpx/Build/Intermediates.noindex/Pods.build/Debug-iphonesimulator/NitroImage.build/Objects-normal/arm64/HybridSwiftKotlinTestObjectSpecCxx.o -index-unit-output-path /Pods.build/Debug-iphonesimulator/NitroImage.build/Objects-normal/arm64/HybridSwiftKotlinTestObjectSpecCxx.o -index-store-path /Users/mrousavy/Library/Developer/Xcode/DerivedData/NitroExample-grbugsgaxfdmulbldokvvxoydqpx/Index.noindex/DataStore -index-system-modules
1.  Apple Swift version 5.10 (swiftlang-5.10.0.13 clang-1500.3.9.4)
2.  Compiling with the current language version
Stack dump without symbol names (ensure you have llvm-symbolizer in your PATH or set the environment var `LLVM_SYMBOLIZER_PATH` to point to it):
0  swift-frontend           0x0000000105ccbf3c llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) + 56
1  swift-frontend           0x0000000105ccb0f8 llvm::sys::RunSignalHandlers() + 112
2  swift-frontend           0x0000000105ccc544 SignalHandler(int) + 360
3  libsystem_platform.dylib 0x000000018631f584 _sigtramp + 56
4  libsystem_pthread.dylib  0x00000001862eec20 pthread_kill + 288
5  libsystem_c.dylib        0x00000001861fba30 abort + 180
6  swift-frontend           0x00000001005d56d8 PrettyStackTraceFrontend::~PrettyStackTraceFrontend() + 0
7  swift-frontend           0x0000000105c14a18 llvm::report_fatal_error(llvm::Twine const&, bool) + 280
8  swift-frontend           0x0000000105c14900 llvm::report_fatal_error(llvm::Twine const&, bool) + 0
9  swift-frontend           0x0000000100aa84b8 llvm::detail::PassModel<llvm::Module, llvm::VerifierPass, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Module>>::printPipeline(llvm::raw_ostream&, llvm::function_ref<llvm::StringRef (llvm::StringRef)>) + 0
10 swift-frontend           0x00000001059cbce8 llvm::PassManager<llvm::Module, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) + 224
11 swift-frontend           0x0000000100a9b490 swift::performLLVMOptimizations(swift::IRGenOptions const&, llvm::Module*, llvm::TargetMachine*, llvm::raw_pwrite_stream*) + 3992
12 swift-frontend           0x0000000100a9cbec swift::performLLVM(swift::IRGenOptions const&, swift::DiagnosticEngine&, llvm::sys::SmartMutex<false>*, llvm::GlobalVariable*, llvm::Module*, llvm::TargetMachine*, llvm::StringRef, llvm::vfs::OutputBackend&, swift::UnifiedStatsReporter*) + 2364
13 swift-frontend           0x00000001005d04f8 generateCode(swift::CompilerInstance&, llvm::StringRef, llvm::Module*, llvm::GlobalVariable*) + 260
14 swift-frontend           0x00000001005ca318 performCompileStepsPostSILGen(swift::CompilerInstance&, std::__1::unique_ptr<swift::SILModule, std::__1::default_delete<swift::SILModule>>, llvm::PointerUnion<swift::ModuleDecl*, swift::SourceFile*>, swift::PrimarySpecificPaths const&, int&, swift::FrontendObserver*) + 2024
15 swift-frontend           0x00000001005c9444 swift::performCompileStepsPostSema(swift::CompilerInstance&, int&, swift::FrontendObserver*) + 608
16 swift-frontend           0x00000001005cd694 performCompile(swift::CompilerInstance&, int&, swift::FrontendObserver*) + 1448
17 swift-frontend           0x00000001005cb6d0 swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 4968
18 swift-frontend           0x000000010055ae8c swift::mainEntry(int, char const**) + 2612
19 dyld                     0x0000000185f660e0 start + 2360

Expected behavior

I expect the Swift closure to properly capture the std::function, so I can call it later. After all, it is a copyable std::function.

Environment

swift-driver version: 1.90.11.1 Apple Swift version 5.10 (swiftlang-5.10.0.13 clang-1500.3.9.4) Target: arm64-apple-macosx14.0

Additional information

No response

mrousavy commented 2 weeks ago

Okay I just found out that the offending piece of code is the self.implementation.someCallback = part.

If I just capture the std::function locally, it works ✅:

set {
  let captured: (_ num: Double) -> Void = { num in
    newValue(num)
  }
}

But as soon as I capture it and assign it to another property (in my case, implementation is a protocol), it fails ❌:

set {
  let captured: (_ num: Double) -> Void = { num in
    newValue(num)
  }
  self.implementation.someCallback = { (num: Double) -> Void in
    captured(num)
  }
}

With this error:

- Global is external, but doesn't have external or weak linkage!
mrousavy commented 2 weeks ago

Are there any workarounds for this?

mrousavy commented 2 weeks ago

I just explicitly wrapped the std::function in a shared_ptr, and now it works:

let shared = bridge.share_Func_void_double(callback)
self.implementation.someCallback = { (value: Double) -> Void in
  shared.pointee.callAsFunction(value)
})

This is a bit hacky and obviously introduces some overhead, so I would prefer to just use the std::function directly. But hey, at least it builds now!