Skip to content

feat: opacity annotations (opaque + transparent-typedef) - #1183

Open
nullstalgia wants to merge 27 commits into
mozilla:mainfrom
nullstalgia:feat/opacity-annotations
Open

nullstalgia wants to merge 27 commits into
mozilla:mainfrom
nullstalgia:feat/opacity-annotations

Conversation

@nullstalgia

Copy link
Copy Markdown
Contributor

This PR aims to add two new per-struct annotations, providing more granular control over the "opacity"/external representation of types defined in Rust that get emitted by cbindgen.

  1. transparent-typedef - (update of Add support for transparent typedefs (take 2) #1029)
    • This is a gentle massage of the original PR by @scovich, with new lints fixed and less change noise.
    • The intent is to allow defining thin wrapper types in Rust, directing cbindgen to emit the wrapped type, not the wrapper.
      • Example:
      • /// cbindgen:transparent-typedef
        #[repr(transparent)]
        struct Handle<T>(Option<NonNull<T>>);
        
        #[unsafe(no_mangle)]
        unsafe extern "C" fn do_object_action(my_object: Handle<Object>) {}
        
        void do_object_action(struct object* my_object);
    • I tried my best to grasp the original underlying design by @scovich, so I'll try my best to answer any questions you have about it,
      but there may be limits to what I can answer confidently.
    • Closes Feature request: transparent/erased typedefs #967, Add support for transparent typedefs #966, Add support for transparent typedefs (take 2) #1029
  2. opaque
    • Allows quickly and definitively marking a type as opaque, regardless of any repr attributes present.
      • Example:
      • /// cbindgen:opaque
        #[repr(C)]
        struct ObjectA {
            field_1: InnerObject,
            field_2: SomeData.
        }
        
        /// cbindgen:opaque
        #[repr(C)]
        struct ObjectB {
            field_1: InnerObject,
            field_2: OtherData.
        }
        
        typedef struct object_a object_a;
        typedef struct object_b object_b;
    • I was toying with potential binding crate design where I essentially was performing type punning in Rust (getting just the first field of a set of structs, getting generic-like functionality.) I ended up using a Rust enum instead (especially to simplify the Dropping of my type), but I still believe this pattern could have merit in a future project/someone else's.
    • Does not work on pub type typedefs, as to not affect intentionally-emitted structs containing said typedefs.
    • There have been numerous other requests for such an annotation: (1, 2, 3)
    • This does not address Support generating opaque type with correct size and alignment for non-#[repr(C)] types #24's variant of this request, but doesn't prevent another PR adding an opaque-sized attribute or similar in the future.

I've also cobbled together a test that ensures the two interact in a sane manner. Let me know if there are edge cases I haven't considered, in the tests or otherwise!

Thanks in advance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature request: transparent/erased typedefs

2 participants