rust-lang / rust-lang/rust-bindgen
Opaque type should not have `pub` member
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 5.3k
- Forks
- 829
- Avg merge
- 1d 1h
- Merged PRs (30d)
- 15
Description
For a type that is explicitly marked opaque via .opaque_type("Foo"), bindgen generates a type with a public member:
#[repr(C)]
#[repr(align(4))]
#[derive(Debug, Default, Copy, Clone)]
pub struct BAR__ {
pub _bindgen_opaque_blob: u32,
}
Shouldn't _bindgen_opaque_blob be generated without pub? Making it pub allows the user to directly instantiate an instance of BAR__ which is most likely invalid, which defeats the purpose of it being an opaque type
Other Information
rust-bindgen 0.71.1
clang version 19.1.7
Target: x86_64-pc-windows-msvc
Full Code Sample
build.rs:
use std::env;
use std::path::PathBuf;
fn main() {
tracing_subscriber::fmt::init();
let builder = bindgen::Builder::default()
.header_contents(
"input.h",
r#"
struct Foo;
struct BAR__{int unused;};
typedef struct BAR__ *BAR;
"#,
)
.parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
.derive_default(true);
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
builder
.clone()
.generate()
.expect("Unable to generate bindings")
.write_to_file((out_path).join("not-explicit-opaque.rs"))
.expect("Couldn't write bindings!");
builder
.opaque_type("Foo")
.opaque_type("BAR__") // Only BAR__ should be marked as opaque. The convenience type BAR should remain as a pointer to the opaque BAR__.
.generate()
.expect("Unable to generate bindings")
.write_to_file((out_path).join("explicit-opaque.rs"))
.expect("Couldn't write bindings!");
}
Output:
not-explicit-opaque.rs:
/* automatically generated by rust-bindgen 0.71.1 */
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct Foo {
_unused: [u8; 0],
}
#[repr(C)]
#[derive(Debug, Default, Copy, Clone)]
pub struct BAR__ {
pub unused: ::std::os::raw::c_int,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
["Size of BAR__"][::std::mem::size_of::<BAR__>() - 4usize];
["Alignment of BAR__"][::std::mem::align_of::<BAR__>() - 4usize];
["Offset of field: BAR__::unused"][::std::mem::offset_of!(BAR__, unused) - 0usize];
};
pub type BAR = *mut BAR__;
explicit-opaque.rs:
/* automatically generated by rust-bindgen 0.71.1 */
#[repr(C)]
#[derive(Debug, Default, Copy, Clone)]
pub struct Foo {
_unused: [u8; 0],
}
#[repr(C)]
#[repr(align(4))]
#[derive(Debug, Default, Copy, Clone)]
pub struct BAR__ {
pub _bindgen_opaque_blob: u32,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
["Size of BAR__"][::std::mem::size_of::<BAR__>() - 4usize];
["Alignment of BAR__"][::std::mem::align_of::<BAR__>() - 4usize];
};
pub type BAR = *mut BAR__;
Output Diff (left is no explicit opaque. right is explicit opaque):
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the bindgen Builder configuration in build.rs and the .opaque_type("BAR__") path; compare explicit-opaque.rs with not-explicit-opaque.rs. Find or add a regression test for generated opaque fields, and verify that the generated blob cannot be directly instantiated while BAR remains a pointer to BAR__.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c, rust
- Domain
- compilers, devtools
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100