Skip to content

Bitfield derive panics when ty uses leading :: (e.g. ::core::ffi::c_uint) #1581

@chisa22

Description

@chisa22

When translating C bitfields, C2Rust generates #[bitfield(...)] attributes with type strings that use a leading ::, e.g.:

#[bitfield(name = "a", ty = "::core::ffi::c_uint", bits = "0..=2")]

However, with the supported toolchain combination (e.g. nightly-2022-08-08 and c2rust-bitfields-derive), this causes the BitfieldStruct derive macro to panic during expansion with:

proc-macro derive panicked
message: `""` is not a valid identifier

Changing the generated code to use a non–leading-:: type string (e.g. ty="c_uint") resolves the issue immediately.
Original C Program

#include <stdio.h>

int main(void) {
    struct {
        unsigned int a : 3;
        unsigned int b : 5;
        unsigned int c : 4;
        int d : 6;          /* signed bitfield */
    } bf = {0};
    
    bf.a = 5;
    printf("Bitfield Test1: Input=5, Result=%u\n", bf.a);
    return 0;
}

C2Rust-Generated Rust

#![allow(
    dead_code,
    non_camel_case_types,
    non_snake_case,
    non_upper_case_globals,
    unused_assignments,
    unused_mut
)]
extern "C" {
    fn printf(__format: *const ::core::ffi::c_char, ...) -> ::core::ffi::c_int;
}
#[derive(Copy, Clone, BitfieldStruct)]
#[repr(C)]
pub struct C2RustUnnamed {
    #[bitfield(name = "a", ty = "::core::ffi::c_uint", bits = "0..=2")]
    #[bitfield(name = "b", ty = "::core::ffi::c_uint", bits = "3..=7")]
    #[bitfield(name = "c", ty = "::core::ffi::c_uint", bits = "8..=11")]
    #[bitfield(name = "d", ty = "::core::ffi::c_int", bits = "12..=17")]
    pub a_b_c_d: [u8; 3],
    #[bitfield(padding)]
    pub c2rust_padding: [u8; 1],
}
unsafe fn main_0() -> ::core::ffi::c_int {
    let mut bf: C2RustUnnamed = {
        let mut init = C2RustUnnamed {
            a_b_c_d: [0; 3],
            c2rust_padding: [0; 1],
        };
        init.set_a(0 as ::core::ffi::c_uint);
        init.set_b(0);
        init.set_c(0);
        init.set_d(0);
        init
    };
    bf.set_a(5 as ::core::ffi::c_uint as ::core::ffi::c_uint);
    printf(
        b"Bitfield Test1: Input=5, Result=%u\n\0" as *const u8
            as *const ::core::ffi::c_char,
        bf.a() as ::core::ffi::c_int,
    );
    return 0 as ::core::ffi::c_int;
}
pub fn main() {
    unsafe { ::std::process::exit(main_0() as i32) }
}

Environment

  • c2rust version: v0.21.0
  • rustc version: nightly-2022-08-08
  • c2rust-bitfields:0.21.0
  • proc-macro2:1.0.103
  • quote:1.0.40
  • syn:2.0.106
  • platform:Ubuntu 24.04

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