swift-bindgen icon indicating copy to clipboard operation
swift-bindgen copied to clipboard

Expressing Rust Move-Only Types in Swift

Open nvzqz opened this issue 6 years ago • 0 comments

In Rust, types that don't implement Copy are considered to be move-only and can only be copied via Clone or other means.

In Swift, there's currently no notion of moving a value. Reassignments of a value result in an implicit copy. For class types or anything that contains a class member, this will increment the strong reference count.

There seems to be three approaches to this:

  1. Retrofit a Move protocol that gives automagical move semantics.

    Pros:

    • Doesn't require Swift users to rewrite any existing code.

    • Allows for deinit on non-class types.

    Cons:

    • Wouldn't work in the context of generics. Implicit copying would still be the default there unless a generic type is specified as Move. Rust's move-only types work in generics because all types are assumed to be move-only unless a generic type is specified as Copy.
  2. Introduce a Copy protocol and assume move-only otherwise. Essentially, just copy Rust.

    Pros:

    • Allows for easier FFI when Swift types cross over into Rust-land.

    • Fine-grained control over move semantics types.

    • Works in the context of generics out-of-the-box.

    Cons:

    • Results in significant added complexity, increasing the learning curve. Implicit copying helps keep Swift succinct and expressive.

    • Massive source compatibility break. Requires stdlib and Swift users to rewrite all implicit copies and opt into Copy where appropriate.

  3. Introduce a special Move<T> wrapper type that gives a type move semantics.

    Pros:

    • Allows for basic move-only types.

    Cons:

    • Doesn't gain much. Really only makes existing code more verbose.

nvzqz avatar Nov 03 '19 01:11 nvzqz