rust-lang / rust-lang/rust-bindgen

Invalid Rust generated when struct-tag namespace and type namespace collide

Open
#3,162 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Rust
Stars
5.3k
Forks
829
Avg merge
1d 1h
Merged PRs (30d)
15

Description

I have encountered a C header file like the following in the wild:

struct A { int x; };
typedef struct A B;

struct B;

void foo(B *b);

When I run rust-bindgen on this and try to compile the resulting Rust, I get a type error due to a redefinition of B:

$ bindgen test.h > test.rs
$ cat test.rs
[ ... ]
pub type B = A;
[ ... ]
struct B { [ ... ] }
$ rustc test.rs
error[E0428]: the name `B` is defined multiple times
  --> test.rs:17:1
   |
14 | pub type B = A;
   | --------------- previous definition of the type `B` here
...
17 | pub struct B {
   | ^^^^^^^^^^^^ `B` redefined here
   |
   = note: `B` must be defined only once in the type namespace of this module

The root problem appears to be that the struct-tag namespace and the type namespace, which are distinct in C, are both projected into the type namespace in Rust, so a name conflict occurs. The C code above is weird and probably doesn't do what the author intends, but it is valid C. For now I've made an edit to the header file, but it would be nice if rust-bindgen would either produce an error in this case, choose one of the definitions, or rename one (B and __struct_B for example?) to avoid the conflict.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by running bindgen on the reported C header and compiling the generated test.rs with rustc to reproduce the duplicate B definition. Trace the generated aliases and structs involved in the struct-tag and type namespaces; done means valid Rust is produced for this valid C input without redefining B, though the desired conflict-resolution policy remains unspecified.

Written by the indexing model from the issue text.

Assessment

Tech stack
c, rust
Domain
devtools
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.