From cb9e0ec4968c0056dd7d2d35948cf65b14688ada Mon Sep 17 00:00:00 2001 From: Emily Schmidt Date: Tue, 15 Oct 2024 10:02:10 +0100 Subject: [PATCH] add bytemuck::NoUninit trait to all Id types --- Cargo.lock | 22 ++++++++++++++++++---- derive/src/id.rs | 5 +++++ ids/Cargo.toml | 1 + ids/src/id.rs | 9 ++++++++- ids/src/id/id_types.rs | 28 ++++++++++++++-------------- ids/src/id/u8_range_types.rs | 8 +++++--- ids/src/lib.rs | 4 ++++ ids/tests/test_id.rs | 2 +- lit/Cargo.toml | 3 +-- lit/src/lit.rs | 2 -- lit/src/var.rs | 2 -- 11 files changed, 57 insertions(+), 29 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 75eb901..98b0d04 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -119,9 +119,23 @@ checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "bytemuck" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94bbb0ad554ad961ddc5da507a12a29b14e4ae5bda06b19f575a3e6079d2e2ae" +checksum = "8334215b81e418a0a7bdb8ef0849474f40bb10c8b71f1c4ed315cff49f32494d" +dependencies = [ + "bytemuck_derive", +] + +[[package]] +name = "bytemuck_derive" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcfcc3cd946cb52f0bbfdbbcfa2f4e24f75ebb6c0e1002f7c25904fada18b9ec" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] [[package]] name = "byteorder" @@ -455,7 +469,8 @@ dependencies = [ name = "imctk-ids" version = "0.1.0" dependencies = [ - "hashbrown 0.14.5", + "bytemuck", + "hashbrown", "imctk-derive", "imctk-transparent", "rand", @@ -492,7 +507,6 @@ dependencies = [ name = "imctk-lit" version = "0.1.0" dependencies = [ - "bytemuck", "flussab-aiger", "hashbrown 0.14.5", "imctk-derive", diff --git a/derive/src/id.rs b/derive/src/id.rs index fd76a6c..944332e 100644 --- a/derive/src/id.rs +++ b/derive/src/id.rs @@ -28,6 +28,7 @@ pub fn derive_id(input: DeriveInput, internal_generic_id: bool) -> syn::Result syn::Result { /// /// Users of this trait may depend on implementing types following these requirements for upholding /// their own safety invariants. -pub unsafe trait Id: Copy + Ord + Hash + Send + Sync + Debug { +pub unsafe trait Id: Copy + Ord + Hash + Send + Sync + Debug + NoUninit { /// An [`Id`] type that has the same representation and index range as this type. /// /// This is provided to enable writing generic code that during monomorphization is only @@ -161,6 +162,12 @@ pub unsafe trait Id: Copy + Ord + Hash + Send + Sync + Debug { #[repr(transparent)] pub struct GenericId(Repr); +// SAFETY: #[repr(transparent)] and the only field is explicitly required to be NoUninit +unsafe impl NoUninit for GenericId where + Repr: Id + NoUninit +{ +} + impl Debug for GenericId { #[inline(always)] fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { diff --git a/ids/src/id/id_types.rs b/ids/src/id/id_types.rs index 1240ef6..8dfb1ec 100644 --- a/ids/src/id/id_types.rs +++ b/ids/src/id/id_types.rs @@ -1,12 +1,12 @@ mod id8 { use imctk_transparent::SubtypeCast; - use crate::id::{u8_range_types::NonMaxHighNibbleU8, ConstIdFromIdIndex, GenericId, Id}; + use crate::id::{u8_range_types::NonMaxHighNibbleU8, ConstIdFromIdIndex, GenericId, Id, NoUninit}; use core::{fmt, fmt::Debug, hash::Hash}; /// [`Id`] type representing indices in the range `0..0xf0`. #[allow(dead_code)] // Only constructed via transmutation and/or pointer casts - #[derive(Clone, Copy)] + #[derive(Clone, Copy, NoUninit)] #[repr(transparent)] pub struct Id8(NonMaxHighNibbleU8); @@ -177,13 +177,13 @@ mod id8 { mod id16 { use imctk_transparent::SubtypeCast; - use crate::id::{u8_range_types::NonMaxU8, ConstIdFromIdIndex, GenericId, Id}; + use crate::id::{u8_range_types::NonMaxU8, ConstIdFromIdIndex, GenericId, Id, NoUninit}; use core::{fmt, fmt::Debug, hash::Hash}; /// [`Id`] type representing indices in the range `0..0xff00`. #[cfg(target_endian = "little")] #[allow(dead_code)] // Only constructed via transmutation and/or pointer casts - #[derive(Clone, Copy)] + #[derive(Clone, Copy, NoUninit)] #[repr(C, align(2))] pub struct Id16 { lsb: u8, @@ -192,7 +192,7 @@ mod id16 { #[cfg(target_endian = "big")] #[allow(dead_code)] // Only constructed via transmutation and/or pointer casts - #[derive(Clone, Copy)] + #[derive(Clone, Copy, NoUninit)] #[repr(C, align(2))] pub struct Id16 { msb: NonMaxU8, @@ -366,13 +366,13 @@ mod id16 { mod id32 { use imctk_transparent::SubtypeCast; - use crate::id::{u8_range_types::NonMaxU8, ConstIdFromIdIndex, GenericId, Id}; + use crate::id::{u8_range_types::NonMaxU8, ConstIdFromIdIndex, GenericId, Id, NoUninit}; use core::{fmt, fmt::Debug, hash::Hash}; /// [`Id`] type representing indices in the range `0..0xff00_0000`. #[cfg(target_endian = "little")] #[allow(dead_code)] // Only constructed via transmutation and/or pointer casts - #[derive(Clone, Copy)] + #[derive(Clone, Copy, NoUninit)] #[repr(C, align(4))] pub struct Id32 { lsbs: [u8; 3], @@ -381,7 +381,7 @@ mod id32 { #[cfg(target_endian = "big")] #[allow(dead_code)] // Only constructed via transmutation and/or pointer casts - #[derive(Clone, Copy)] + #[derive(Clone, Copy, NoUninit)] #[repr(C, align(4))] pub struct Id32 { msb: NonMaxU8, @@ -562,13 +562,13 @@ mod id32 { mod id64 { use imctk_transparent::SubtypeCast; - use crate::id::{u8_range_types::NonMaxU8, ConstIdFromIdIndex, GenericId, Id}; + use crate::id::{u8_range_types::NonMaxU8, ConstIdFromIdIndex, GenericId, Id, NoUninit}; use core::{fmt, fmt::Debug, hash::Hash}; /// [`Id`] type representing indices in the range `0..0xff00_0000_0000_0000`. #[cfg(target_endian = "little")] #[allow(dead_code)] // Only constructed via transmutation and/or pointer casts - #[derive(Clone, Copy)] + #[derive(Clone, Copy, NoUninit)] #[repr(C, align(8))] pub struct Id64 { lsbs: [u8; 7], @@ -577,7 +577,7 @@ mod id64 { #[cfg(target_endian = "big")] #[allow(dead_code)] // Only constructed via transmutation and/or pointer casts - #[derive(Clone, Copy)] + #[derive(Clone, Copy, NoUninit)] #[repr(C, align(8))] pub struct Id64 { msb: NonMaxU8, @@ -758,7 +758,7 @@ mod id64 { mod id_size { use imctk_transparent::SubtypeCast; - use crate::id::{u8_range_types::NonMaxMsbU8, ConstIdFromIdIndex, GenericId, Id}; + use crate::id::{u8_range_types::NonMaxMsbU8, ConstIdFromIdIndex, GenericId, Id, NoUninit}; use core::{fmt, fmt::Debug, hash::Hash}; const LSBS: usize = (usize::BITS as usize / 8) - 1; @@ -766,7 +766,7 @@ mod id_size { /// [`Id`] type representing indices in the range `0..=isize::MAX as usize`. #[cfg(target_endian = "little")] #[allow(dead_code)] // Only constructed via transmutation and/or pointer casts - #[derive(Clone, Copy)] + #[derive(Clone, Copy, NoUninit)] #[cfg_attr(target_pointer_width = "16", repr(C, align(2)))] #[cfg_attr(target_pointer_width = "32", repr(C, align(4)))] #[cfg_attr(target_pointer_width = "64", repr(C, align(8)))] @@ -777,7 +777,7 @@ mod id_size { #[cfg(target_endian = "big")] #[allow(dead_code)] // Only constructed via transmutation and/or pointer casts - #[derive(Clone, Copy)] + #[derive(Clone, Copy, NoUninit)] #[cfg_attr(target_pointer_width = "16", repr(C, align(2)))] #[cfg_attr(target_pointer_width = "32", repr(C, align(4)))] #[cfg_attr(target_pointer_width = "64", repr(C, align(8)))] diff --git a/ids/src/id/u8_range_types.rs b/ids/src/id/u8_range_types.rs index e5ba744..69a607f 100644 --- a/ids/src/id/u8_range_types.rs +++ b/ids/src/id/u8_range_types.rs @@ -1,5 +1,7 @@ +use crate::NoUninit; + #[allow(dead_code)] // Only constructed via transmutation and/or pointer casts -#[derive(Clone, Copy)] +#[derive(Clone, Copy, NoUninit)] #[repr(u8)] pub enum NonMaxU8 { Val00 = 0x00, @@ -260,7 +262,7 @@ pub enum NonMaxU8 { } #[allow(dead_code)] // Only constructed via transmutation and/or pointer casts -#[derive(Clone, Copy)] +#[derive(Clone, Copy, NoUninit)] #[repr(u8)] pub enum NonMaxHighNibbleU8 { Val00 = 0x00, @@ -506,7 +508,7 @@ pub enum NonMaxHighNibbleU8 { } #[allow(dead_code)] // Only constructed via transmutation and/or pointer casts -#[derive(Clone, Copy)] +#[derive(Clone, Copy, NoUninit)] #[repr(u8)] pub enum NonMaxMsbU8 { Val00 = 0x00, diff --git a/ids/src/lib.rs b/ids/src/lib.rs index 931307a..a65669b 100644 --- a/ids/src/lib.rs +++ b/ids/src/lib.rs @@ -31,3 +31,7 @@ pub use imctk_derive::Id; pub use id::{ConstIdFromIdIndex, GenericId, Id, Id16, Id32, Id64, Id8, IdSize}; pub use id_range::IdRange; + +// re-export this so that others can use it without depending on bytemuck explicitly +// in particular needed for #[derive(Id)] +pub use bytemuck::NoUninit; \ No newline at end of file diff --git a/ids/tests/test_id.rs b/ids/tests/test_id.rs index 6df140f..0292768 100644 --- a/ids/tests/test_id.rs +++ b/ids/tests/test_id.rs @@ -383,7 +383,7 @@ fn conversion_usize() { #[derive(Id)] #[repr(transparent)] -pub struct NewtypePhantom(usize, PhantomData); +pub struct NewtypePhantom(usize, PhantomData); impl std::fmt::Debug for NewtypePhantom { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { diff --git a/lit/Cargo.toml b/lit/Cargo.toml index 1b29ee4..f9b5cf0 100644 --- a/lit/Cargo.toml +++ b/lit/Cargo.toml @@ -18,5 +18,4 @@ imctk-transparent = { version = "0.1.0", path = "../transparent" } imctk-util = { version = "0.1.0", path = "../util" } log = "0.4.21" table_seq = { version = "0.1.0", path = "../table_seq" } -zwohash = "0.1.2" -bytemuck = "*" \ No newline at end of file +zwohash = "0.1.2" \ No newline at end of file diff --git a/lit/src/lit.rs b/lit/src/lit.rs index 0aa1a31..409869c 100644 --- a/lit/src/lit.rs +++ b/lit/src/lit.rs @@ -24,8 +24,6 @@ use super::{pol::Pol, var::Var}; #[derive(Id, SubtypeCast, NewtypeCast)] pub struct Lit(Id32); -unsafe impl bytemuck::NoUninit for Lit {} - /// Ensure that there is an even number of literals #[allow(clippy::assertions_on_constants)] const _: () = { diff --git a/lit/src/var.rs b/lit/src/var.rs index 473ebc4..ce9fc3a 100644 --- a/lit/src/var.rs +++ b/lit/src/var.rs @@ -9,8 +9,6 @@ use super::{lit::Lit, pol::Pol}; #[derive(Id, SubtypeCast, NewtypeCast)] pub struct Var(GenericId<{ Lit::MAX_ID_INDEX / 2 }, ::BaseId>); -unsafe impl bytemuck::NoUninit for Var {} - impl std::fmt::Debug for Var { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self, f)