diff --git a/Cargo.toml b/Cargo.toml index 99e20896b1..57a0c02d43 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -120,6 +120,7 @@ strum = "0.26.3" strum_macros = "0.26.4" toml = "0.8.19" # For parsing the injections toml file typed-builder = "0.20.0" # Implement the builder pattern at compiletime +typeid = "1.0.0" # Safe type_eq that doesn't rely on std specialization uuid = { version = "1.10.0", features = ["serde", "v4"] } which = "6.0.3" windows = "0.59.0" diff --git a/libafl_bolts/Cargo.toml b/libafl_bolts/Cargo.toml index 4eb69551be..f52953b1ac 100644 --- a/libafl_bolts/Cargo.toml +++ b/libafl_bolts/Cargo.toml @@ -122,6 +122,7 @@ rustversion = { workspace = true } [dependencies] libafl_derive = { workspace = true, default-features = true, optional = true } static_assertions = { workspace = true } +typeid = { workspace = true } tuple_list = { version = "0.1.3" } hashbrown = { workspace = true, features = [ diff --git a/libafl_bolts/src/tuples.rs b/libafl_bolts/src/tuples.rs index d1e779155a..a8ff63a925 100644 --- a/libafl_bolts/src/tuples.rs +++ b/libafl_bolts/src/tuples.rs @@ -6,9 +6,10 @@ use alloc::{borrow::Cow, vec::Vec}; use core::{ any::type_name, fmt::{Debug, Formatter}, + marker::PhantomData, ops::{Deref, DerefMut, Index, IndexMut}, }; -use core::{any::TypeId, cell::Cell, marker::PhantomData, mem::transmute}; +use core::{any::TypeId, mem::transmute}; #[cfg(feature = "alloc")] use serde::{Deserialize, Serialize}; @@ -21,36 +22,9 @@ use crate::HasLen; use crate::Named; /// Returns if the type `T` is equal to `U`, ignoring lifetimes. -#[inline] // this entire call gets optimized away :) #[must_use] pub fn type_eq() -> bool { - // decider struct: hold a cell (which we will update if the types are unequal) and some - // phantom data using a function pointer to allow for Copy to be implemented - struct W<'a, T: ?Sized, U: ?Sized>(&'a Cell, PhantomData (&'a T, &'a U)>); - - // default implementation: if the types are unequal, we will use the clone implementation - impl Clone for W<'_, T, U> { - #[inline] - fn clone(&self) -> Self { - // indicate that the types are unequal - // unfortunately, use of interior mutability (Cell) makes this not const-compatible - // not really possible to get around at this time - self.0.set(false); - W(self.0, self.1) - } - } - - // specialized implementation: Copy is only implemented if the types are the same - #[expect(clippy::mismatching_type_param_order)] - impl Copy for W<'_, T, T> {} - - let detected = Cell::new(true); - // [].clone() is *specialized* in core. - // Types which implement copy will have their copy implementations used, falling back to clone. - // If the types are the same, then our clone implementation (which sets our Cell to false) - // will never be called, meaning that our Cell's content remains true. - let res = [W::(&detected, PhantomData)].clone(); - res[0].0.get() + typeid::of::() == typeid::of::() } /// Borrow each member of the tuple @@ -955,8 +929,6 @@ mod test { } #[test] - #[cfg(feature = "alloc")] - #[expect(unused_qualifications)] // for type name tests fn test_type_eq() { // An alias for equality testing type OwnedMutSliceAlias<'a> = OwnedMutSlice<'a, u8>; @@ -976,15 +948,6 @@ mod test { // test weirder lifetime things assert!(type_eq::, OwnedMutSlice>()); assert!(!type_eq::, OwnedMutSlice>()); - - assert!(type_eq::< - OwnedMutSlice, - crate::ownedref::OwnedMutSlice, - >()); - assert!(!type_eq::< - OwnedMutSlice, - crate::ownedref::OwnedMutSlice, - >()); } #[test]