rust-lang / rust-lang/rust-bindgen
`no_copy`, `no_hash`, `no_partialeq` are ignored
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 5.3k
- Forks
- 829
- Avg merge
- 1d 1h
- Merged PRs (30d)
- 15
Description
I am trying to generate bindings for a C enum, and make the resulting Rust type not derive Copy, Clone, Hash, PartialEq, Eq:
/* netlink.h */
#ifndef _SINF_NETLINK_H
#define _SINF_NETLINK_H
enum sinf_command {
SINF_C_UNSPEC,
SINF_C_GET,
};
#endif /* _SINF_NETLINK_H */
I tried using no_copy, no_hash etc, but they don't seem to work. Here is a small example that reproduces my issue:
/* main.rs */
use bindgen::callbacks::ParseCallbacks;
use bindgen::EnumVariation;
/// Helper for applying custom attributes to enums.
#[derive(Debug)]
struct NeliEnum;
impl ParseCallbacks for NeliEnum {
/*
fn add_attributes(&self, _info: &AttributeInfo<'_>) -> Vec<String> {
// I want to apply neli::neli_enum, which derives Copy, Clone, etc.,
// so I need to prevent bindgen from deriving them too.
vec!["#[neli::neli_enum(serialized_type = \"u8\")]".into()]
}
*/
}
fn main() {
let bindings = bindgen::Builder::default()
.default_enum_style(EnumVariation::Rust { non_exhaustive: false })
.parse_callbacks(Box::new(NeliEnum))
.header("./netlink.h")
// This works
.no_debug(".*")
// This doesn't work quite as advertised: the docs say
// this will suppress both Copy and Clone, but in this case,
// it looks like it only suppresses Copy?
.no_copy(".*")
// Does not work, Hash is still derived for sinf_command
.no_hash(".*")
// Does not work, PartialEq is still derived for sinf_command
.no_partialeq(".*")
.generate()
.expect("Unable to generate bindings");
bindings
.write_to_file("./src/netlink.rs")
.expect("Couldn't write bindings!");
}
My Cargo.toml is:
[package]
name = "sinf"
version = "0.1.0"
edition = "2024"
[dependencies]
bindgen = "0.71.0"
Expected output
/* automatically generated by rust-bindgen 0.71.1 */
#[repr(u32)]
pub enum sinf_command {
SINF_C_UNSPEC = 0,
SINF_C_GET = 1,
}
Actual output
/* automatically generated by rust-bindgen 0.71.1 */
#[repr(u32)]
#[derive(Clone, Hash, PartialEq, Eq)]
pub enum sinf_command {
SINF_C_UNSPEC = 0,
SINF_C_GET = 1,
}
I am also confused by the derive_hash, etc. docs, which seem to suggest these traits shouldn't have been derived at all:
Set whether the Hash trait should be derived when possible.
Hash is not derived by default.
Are the docs wrong, or is this a separate bug? Or am I somehow misinterpreting them?
For context, I'm trying to generate bindings for some netlink types that are shared between a kernel module and my userspace application.
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 Rust enum-generation path behind Builder::no_copy, no_hash, and no_partialeq, using the provided netlink.h and main.rs reproducer. Check how these options interact with EnumVariation::Rust and ParseCallbacks::add_attributes; done means the generated sinf_command has none of the unwanted derives while callback-added attributes remain possible.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100