[rust-dev] wrapping a C library (ownership/mutability questions)

Josh Haberman jhaberman at gmail.com
Sat Jan 18 13:24:54 PST 2014


On Fri, Jan 17, 2014 at 5:07 PM, Daniel Micay <danielmicay at gmail.com> wrote:
> Every type in Rust can be assigned, passed or returned by-value. This
> is always semantically equivalent to a shallow copy, as they are in C.
> If the type has a destructor, closure or `&mut T` inside then the copy
> is considered a move of ownership.

Interesting. I have also learned (thanks to people on IRC) that you
cannot move out of a borrowed pointer. So this gave me a new idea for
the wrapper that I have written a little prototype for:

https://gist.github.com/haberman/8496516

And this is the little fake version of my library you can link against it:

https://gist.github.com/haberman/8496487

The idea behind this wrapper is that we model my C type as a Rust unit
struct (with no members) that serves only to hold the pointer and
methods on the struct. But the wrapper only allows you to obtain
borrowed refs to this struct through Arc-like get() methods, so you
can never do an ownership move (and can therefore never convert a
non-mut ref into a mut ref).

Then any functions that want to take my type as a parameter just
accept a borrowed, non-mut reference. They can nicely accept either
mut or non-mut references:

fn algorithm_on_fielddef(f: &FieldDef) {
  // ...
}

I just realized unfortunately that this scheme can't prevent the user
from saying:

  let field_def = FieldDef;
  field_def.number();  // Crash, this isn't actually a legitimate FieldDef.

Any way to prevent this, so that only I am allowed to create FieldDef
structs but can still return references to them in my public API?

Thanks,
Josh


More information about the Rust-dev mailing list