Skip to content

no_copy, no_hash, no_partialeq are ignored #3168

Open
@gabi-250

Description

@gabi-250

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions