Description
Replying to #1651 (comment) as a new issue
My initial comment was "these generated tests sure don't seem to actually be useful" and then I was asked for an explanation.
So, I guess it depends on who these tests are for.
let's look at an example
#[repr(C)]
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct SDL_AssertData {
pub always_ignore: winapi::ctypes::c_int,
pub trigger_count: winapi::ctypes::c_uint,
pub condition: *const winapi::ctypes::c_char,
pub filename: *const winapi::ctypes::c_char,
pub linenum: winapi::ctypes::c_int,
pub function: *const winapi::ctypes::c_char,
pub next: *const SDL_AssertData,
}
#[test]
fn bindgen_test_layout_SDL_AssertData() {
assert_eq!(
::core::mem::size_of::<SDL_AssertData>(),
48usize,
concat!("Size of: ", stringify!(SDL_AssertData))
);
assert_eq!(
::core::mem::align_of::<SDL_AssertData>(),
8usize,
concat!("Alignment of ", stringify!(SDL_AssertData))
);
assert_eq!(
unsafe { &(*(::core::ptr::null::<SDL_AssertData>())).always_ignore as *const _ as usize },
0usize,
concat!(
"Offset of field: ",
stringify!(SDL_AssertData),
"::",
stringify!(always_ignore)
)
);
// and it goes on and on for all the other fields.
}
(We're ignoring the "derefing a null pointer" UB, which the other issue covers, we have to ask ourselves what these tests are intended to check.)
So the Rust types have defined widths and alignments, but the C types are implemented as aliases and they theoretically vary by platform (c_int
isn't necessarily always i32
, it just usually is).
Now maybe it's a useful thing to have a test where we assert the sizes we expect for the C types based on the local C types when we generated the bindings. You might care to know that the bindings were generated on one machine where C was like "x" and now you're on a machine where C is like "y".
If we do want to check that the local C environment is the same as the one bindgen saw when it ran, we should do that via a single test once at the top of the module:
#[test]
fn test_local_c_env_matches_bindgen_c_env(){
// assert stuff here
}
We should not have tests per field per struct spread all across the module basically asserting that 2+2 is 4 for thousands of lines.
On the other hand, it's entirely possible that you don't care that the target C environment doesn't match the C environment at the time of running bindgen, because you expected that, and all the structs are defined in terms of the ctype aliases so with the local aliases they've already been corrected to the proper sizes. In this scenario, the current test suite system of being per field is also still mostly useless, since if you have just a single test_local_c_env_matches_bindgen_c_env
function that tells you about the changes too.
Either way, we don't need to have size, alignment, and field offset tests per struct. I can't see what scenario that it's guarding against that having a single test of the local ctypes doesn't solve.