From fae1b0b2225834450a32ddb866afa7f212d996c1 Mon Sep 17 00:00:00 2001 From: acheronfail Date: Sat, 30 Dec 2023 22:30:29 +1030 Subject: [PATCH] fix warning when compiling on aarch64 platforms --- src/util/netlink/acpi/ffi.rs | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/src/util/netlink/acpi/ffi.rs b/src/util/netlink/acpi/ffi.rs index b33b377..4c25bbe 100644 --- a/src/util/netlink/acpi/ffi.rs +++ b/src/util/netlink/acpi/ffi.rs @@ -1,5 +1,6 @@ use ::std::os::raw::{c_char, c_uint}; use serde_derive::{Deserialize, Serialize}; +use std::any::TypeId; use crate::error::{Error, Result}; @@ -50,17 +51,28 @@ impl AcpiGenericNetlinkEvent { /// Checks a slice of C's chars to ensure they're not signed, needed because C's `char` type could /// be either signed or unsigned unless specified. See: https://stackoverflow.com/a/2054941/5552584 fn get_u8_bytes(slice: &[c_char]) -> Result> { - slice - .into_iter() - .take_while(|c| **c != 0) - .map(|c| -> Result { - if *c < 0 { - Err(format!("slice contained signed char: {}", c).into()) - } else { - Ok(*c as u8) - } - }) - .collect::>>() + // NOTE: on some platforms `c_char` is `i8` and on others it's `u8`. Instead of targeting those + // directly with `#cfg[...]` attributes (because it's not straightforward, have a look at the + // cfg match for `c_char` in the stdlib, it's huge) we instead perform a runtime comparison + // with `TypeId` here. + // According to my tests (with `cargo-show-asm`), this is always optimised out completely since + // `TypeId` returns a constant value, so it's just as good as a compile-time check. + if TypeId::of::() == TypeId::of::() { + slice + .into_iter() + .take_while(|c| **c != 0) + .map(|c| -> Result { + #[allow(unused_comparisons)] + if *c < 0 { + Err(format!("slice contained signed char: {}", c).into()) + } else { + Ok(*c as u8) + } + }) + .collect::>>() + } else { + Ok(slice.iter().map(|&c| c as u8).collect()) + } } impl<'a> TryFrom<&'a acpi_genl_event> for AcpiGenericNetlinkEvent {