dead_code suggestion would break the semantics of code using#[repr(transparent)]
· Issue #119659 · rust-lang/rust (original) (raw)
This occurs in aya:
https://github.com/aya-rs/aya/blob/e1aefa4e87970553dc60549141b3b4cf883f4366/bpf/aya-bpf/src/helpers.rs#L734-L737
On a nightly that includes #118297 I get:
error: field `0` is never read
--> bpf/aya-bpf/src/helpers.rs:737:22
|
737 | pub struct PrintkArg(u64);
| --------- ^^^
| |
| field in this struct
|
= note: `PrintkArg` has a derived impl for the trait `Clone`, but this is intentionally ignored during dead code analysis
= note: `-D dead-code` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(dead_code)]`
help: consider changing the field to be of unit type to suppress this warning while preserving the field numbering, or remove the field
|
737 | pub struct PrintkArg(());
In a strict sense the compiler is correct. That's because PrintkArg
is used like so:
pub unsafe fn bpf_printk_impl<const FMT_LEN: usize, const NUM_ARGS: usize>(
fmt: &[u8; FMT_LEN],
args: &[PrintkArg; NUM_ARGS],
) -> i64 {
// This function can't be wrapped in helpers.rs
because it has variadic
// arguments. We also can't turn the definitions in helpers.rs
into
// const
s because MIRI believes casting arbitrary integers to function
// pointers to be an error.
let printk: unsafe extern "C" fn(fmt: *const c_char, fmt_size: u32, ...) -> c_long =
mem::transmute(6usize);
let fmt_ptr = fmt.as_ptr() as *const c_char;
let fmt_size = fmt.len() as u32;
match NUM_ARGS {
0 => printk(fmt_ptr, fmt_size),
1 => printk(fmt_ptr, fmt_size, args[0]),
2 => printk(fmt_ptr, fmt_size, args[0], args[1]),
3 => printk(fmt_ptr, fmt_size, args[0], args[1], args[2]),
_ => gen::bpf_trace_vprintk(fmt_ptr, fmt_size, args.as_ptr() as _, (NUM_ARGS * 8) as _),
}
}
Thus the compiler's suggestion would break the semantics of this code. Playground. /cc @shepmaster