swift-bridge 0.1.59 produces malformed Swift code in the generated wrapper for extern "Swift" functions with the signature fn(input: &[u8]) -> Vec<u8>.
This is distinct from #228 (which covers the Vec<u8> return-type implementation; that fix landed). The Vec<u8> return marshaling itself works — the bug is in the &[u8] input-side marshaling, where the slice unpacking is emitted in expression position rather than statement position.
Reproducer
// src/bridge.rs
#[swift_bridge::bridge]
mod ffi {
extern "Swift" {
fn my_hash(input: &[u8]) -> Vec<u8>;
}
}
Generated Swift (from cargo build)
@_cdecl("__swift_bridge__$my_hash")
func __swift_bridge__my_hash (_ input: __private__FfiSlice) -> UnsafeMutableRawPointer {
{ let val = my_hash(input: let slice = input; return UnsafeBufferPointer(start: slice.start.assumingMemoryBound(to: UInt8.self), count: Int(slice.len));); val.isOwned = false; return val.ptr }()
}
The inlined let slice = input; return UnsafeBufferPointer(...) cannot appear in expression position inside the my_hash(input: ...) argument — let and return are statements in Swift, not expressions. The Swift compiler rejects this with error: expected expression.
Likely fix
The slice unpacking needs to be hoisted to a statement above the call:
@_cdecl("__swift_bridge__$my_hash")
func __swift_bridge__my_hash (_ input: __private__FfiSlice) -> UnsafeMutableRawPointer {
let slice = UnsafeBufferPointer(start: input.start.assumingMemoryBound(to: UInt8.self), count: Int(input.len))
let val = my_hash(input: slice)
val.isOwned = false
return val.ptr
}
Looks like a missed case in swift-bridge-ir's expression-flattener for the &[u8] input-side marshaling specifically.
Workaround in use
Hex-encoded String -> String signatures (Rust passes hex string, Swift decodes + processes + returns hex). Functional but adds encode/decode CPU overhead. Not viable in hot paths so we'd appreciate a fix.
Environment
- swift-bridge 0.1.59
- swift 6.2.3 (Apple Swift)
- macOS 26.0 / aarch64-apple-darwin
Happy to provide a minimal repro project if useful. Thanks for the great library!
swift-bridge 0.1.59 produces malformed Swift code in the generated wrapper for
extern "Swift"functions with the signaturefn(input: &[u8]) -> Vec<u8>.This is distinct from #228 (which covers the
Vec<u8>return-type implementation; that fix landed). TheVec<u8>return marshaling itself works — the bug is in the&[u8]input-side marshaling, where the slice unpacking is emitted in expression position rather than statement position.Reproducer
Generated Swift (from
cargo build)The inlined
let slice = input; return UnsafeBufferPointer(...)cannot appear in expression position inside themy_hash(input: ...)argument —letandreturnare statements in Swift, not expressions. The Swift compiler rejects this witherror: expected expression.Likely fix
The slice unpacking needs to be hoisted to a statement above the call:
Looks like a missed case in
swift-bridge-ir's expression-flattener for the&[u8]input-side marshaling specifically.Workaround in use
Hex-encoded
String -> Stringsignatures (Rust passes hex string, Swift decodes + processes + returns hex). Functional but adds encode/decode CPU overhead. Not viable in hot paths so we'd appreciate a fix.Environment
Happy to provide a minimal repro project if useful. Thanks for the great library!