Skip to content

Swift 6.2: Generated code collides with new Data.bytes property (SE-0456) #2803

@llbartekll

Description

@llbartekll

Problem

Swift 6.2 introduced a new Data.bytes property that returns RawSpan (via SE-0456). This collides with UniFFI's generated Swift code which uses bytes as a parameter name.

Generated code that causes the issue

fileprivate extension RustBuffer {
    // Allocate a new buffer, copying the contents of a `UInt8` array.
    init(bytes: [UInt8]) {
        let rbuf = bytes.withUnsafeBufferPointer { ptr in
            RustBuffer.from(ptr)
        }
        self.init(capacity: rbuf.capacity, len: rbuf.len, data: rbuf.data)
    }
    // ...
}

Compilation errors

When building with Xcode 26.x / Swift 6.2.x:

  1. Cannot convert value of type 'RawSpan' to expected argument type 'UnsafePointer<UInt8>'
  2. Ambiguous use of 'bytes'

The Swift compiler gets confused between:

  • The local parameter bytes: [UInt8]
  • The new Data.bytes property returning RawSpan

Suggested Fix

Rename the bytes parameter to something that won't collide, like byteArray:

fileprivate extension RustBuffer {
    init(byteArray: [UInt8]) {
        let rbuf = byteArray.withUnsafeBufferPointer { ptr in
            RustBuffer.from(ptr)
        }
        self.init(capacity: rbuf.capacity, len: rbuf.len, data: rbuf.data)
    }
}

And update the call site:

// From:
return RustBuffer(bytes: writer)
// To:
return RustBuffer(byteArray: writer)

Workaround

We've implemented a post-processing sed script that patches the generated Swift code:

sed -i '' 's/init(bytes: \[UInt8\])/init(byteArray: [UInt8])/g' "$swift_file"
sed -i '' 's/let rbuf = bytes\.withUnsafeBufferPointer/let rbuf = byteArray.withUnsafeBufferPointer/g' "$swift_file"
sed -i '' 's/RustBuffer(bytes: writer)/RustBuffer(byteArray: writer)/g' "$swift_file"

This is backwards compatible and works on both Swift 5.x and Swift 6.x.

Environment

  • UniFFI version: 0.31.0
  • Swift version: 6.2.3 (Xcode 26.2)
  • Platform: iOS/macOS

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions