rust-lang / rust-lang/rust-bindgen
Derive analysis manual selection is too conservative
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 5.3k
- Forks
- 829
- Avg merge
- 1d 1h
- Merged PRs (30d)
- 15
Description
Input C/C++ Header
typedef struct {
int (*foo) (int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9, int a10, int a11, int a12, int a13);
} a;
typedef struct {
int foo[4096];
} b;
typedef struct {
a a;
b b;
} combined;
Bindgen Invocation
bindgen::Builder::default()
.header("input.h")
.trust_clang_mangling(false)
.derive_copy(false)
.derive_debug(true)
.impl_debug(true)
.derive_default(true)
.layout_tests(false)
.generate()
.unwrap()
Actual Results
I'm omitting output for struct a and struct b but please note that they do already implement Debug and Default.
#[repr(C)]
pub struct combined {
pub a: a,
pub b: b,
}
impl Default for combined {
fn default() -> Self {
unsafe { ::std::mem::zeroed() }
}
}
impl ::std::fmt::Debug for combined {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
write!(f, "combined {{ a: {:?}, b: {:?} }}", self.a, self.b)
}
}
Expected Results
Since struct a and struct b do get a manual implementation of Debug and Default, it should just be possible to derive them for struct combined. However, a manual implementation is generated by bindgen instead of just doing:
#[repr(C)]
#[derive(Debug, Default)]
pub struct combined {
pub a: a,
pub b: b,
}
Cause
The monotone constraint analysis for derive is too conservative. CanDerive::Manually means both that a type needs a manual implementation of a trait, as well as that the type, when included as a member of another type, requires manual implementations of a trait in the containing type. Since we use this one value to mean both things, if a type needs manual implementation due to one of its members, that is then automatically interpreted as that type triggering manual implementation in its containing types as well.
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 at the bindgen::Builder invocation and trace derive analysis for combined, including its a and b fields. Done means generated combined can use #[derive(Debug, Default)] when those member types have manual implementations, without incorrectly forcing a manual implementation in the containing type; verify the behavior with the supplied C++ header.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp, rust
- Domain
- compilers, tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100