Avoid _bindgen_ty_ indirection #377

daschl opened this Issue Jan 4, 2017 · 4 comments


None yet

3 participants

daschl commented Jan 4, 2017 edited


I'm using rust-bindgen to generate bindings for libcouchbase. It works fine in general, but I noticed that for example this typedef enum:

typedef enum {
    LCB_KV_COPY = 0, /**< The buffer should be copied */
    LCB_KV_CONTIG, /**< The buffer is contiguous and should not be copied */
    LCB_KV_IOV, /**< The buffer is not contiguous and should not be copied */

    /**For use within the hashkey field, indicates that the _length_
     * of the hashkey is the vBucket ID, rather than an actual hashkey */

     * The buffers are not contiguous (multi-part buffers) but should be
     * copied. This avoids having to make the buffers contiguous before
     * passing it into the library (only to have the library copy it again) */

Gets abstracted as _bindgen_ty_10 and then a type alias of type lcb_KVBUFTYPE = _bindgen_ty_10; is defined as well. It wouldn't be much of an issue (other than making the rustdoc very noisy since there are many similar types), but then later on in the code I can't pattern match/use the enum variants because of rust-lang/rust#26264 directly.

As a result, I end up writing _bindgen_ty_10::LCB_KV_COPY which defeats the purpose of the alias mostly.

So, is there either a workaround or an option to avoid this indirection and just name the enums/structs directly after what they are called in C code?

Note that this can be easily reproduced by cloning and building https://github.com/couchbaselabs/couchbase-rs/tree/master/couchbase-sys, and I'm happy to help getting it to run :)


emilio commented Jan 4, 2017

Ah, that annoying rust bug, thanks for filling.

Yes, I think we can do multiple things here:

First, when generating a typedef, if the inner type is an enum, we can just generate a pub use statement instead of a pub type. That'd be straight-forward to implement I think, let me know if you're interested (I can probably get to it this or next week).

This should work fine given you can't have a templatized-enum in C/C++, so we shouldn't have issues there. Also, we can constrain it even more if we just do so for unnamed enums.

Other thing we may do, is trying to detect that pattern (typedef enum { } foo;) and just generate the enum as-if it was called foo. This is doable, but more prone to subtle bugs IMO.

Let me know if you'd be interested in fixing that. The relevant code is libbindgen/src/codegen/mod.rs:487. In that branch we should check for whether inner_item is an enum, and then generate a pub use instead of a pub type. As I wrote above, I don't think we need to care about applicable_template_args and all that mess, so should be straight-forward :)

Thanks for reporting this!

@emilio emilio added the enhancement label Jan 4, 2017
emilio commented Jan 18, 2017

FYI I wrote #396 which should solve this cleanly.

Waiting on @fitzgen to come back so it gets reviewed :)

Thanks for reporting it!

daschl commented Jan 19, 2017

Awesome, looking forward to it - thanks!

fitzgen commented Jan 19, 2017

Fixed in #396.

@fitzgen fitzgen closed this Jan 19, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment