diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
commit | 2aa4a82499d4becd2284cdb482213d541b8804dd (patch) | |
tree | b80bf8bf13c3766139fbacc530efd0dd9d54394c /third_party/rust/memoffset-0.5.1 | |
parent | Initial commit. (diff) | |
download | firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.tar.xz firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.zip |
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/memoffset-0.5.1')
-rw-r--r-- | third_party/rust/memoffset-0.5.1/.cargo-checksum.json | 1 | ||||
-rw-r--r-- | third_party/rust/memoffset-0.5.1/Cargo.toml | 24 | ||||
-rw-r--r-- | third_party/rust/memoffset-0.5.1/LICENSE | 19 | ||||
-rw-r--r-- | third_party/rust/memoffset-0.5.1/README.md | 54 | ||||
-rw-r--r-- | third_party/rust/memoffset-0.5.1/build.rs | 12 | ||||
-rw-r--r-- | third_party/rust/memoffset-0.5.1/src/lib.rs | 76 | ||||
-rw-r--r-- | third_party/rust/memoffset-0.5.1/src/offset_of.rs | 135 | ||||
-rw-r--r-- | third_party/rust/memoffset-0.5.1/src/span_of.rs | 268 |
8 files changed, 589 insertions, 0 deletions
diff --git a/third_party/rust/memoffset-0.5.1/.cargo-checksum.json b/third_party/rust/memoffset-0.5.1/.cargo-checksum.json new file mode 100644 index 0000000000..63fad95bcd --- /dev/null +++ b/third_party/rust/memoffset-0.5.1/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"7a81dbe83677240751ea16029792a46d0a776886ecae85f18fbec6c5912543c3","LICENSE":"3234ac55816264ee7b6c7ee27efd61cf0a1fe775806870e3d9b4c41ea73c5cb1","README.md":"f79665fcf1b936024d74465c45f65d6e3157be593b4507be27729d6eff613047","build.rs":"ba401d756f3007247cdc74f2b749deee11cec48d98d6deaa49677c0cfc3ef0ae","src/lib.rs":"278bbe15039e745385f8bf7cf3b005c4c5404e403c732de5aa936b7dd19cd0e9","src/offset_of.rs":"734576bb3f91e33fe2737d8a036623b5d850521401d6321b844a3da418057dee","src/span_of.rs":"84a073a394254b84f52f3d89aafdd7ce7b87f8587f6a41a5868aa428aa740b19"},"package":"ce6075db033bbbb7ee5a0bbd3a3186bbae616f57fb001c485c7ff77955f8177f"}
\ No newline at end of file diff --git a/third_party/rust/memoffset-0.5.1/Cargo.toml b/third_party/rust/memoffset-0.5.1/Cargo.toml new file mode 100644 index 0000000000..f6add76060 --- /dev/null +++ b/third_party/rust/memoffset-0.5.1/Cargo.toml @@ -0,0 +1,24 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies +# +# If you believe there's an error in this file please file an +# issue against the rust-lang/cargo repository. If you're +# editing this file be aware that the upstream Cargo.toml +# will likely look very different (and much more reasonable) + +[package] +name = "memoffset" +version = "0.5.1" +authors = ["Gilad Naaman <gilad.naaman@gmail.com>"] +description = "offset_of functionality for Rust structs." +readme = "README.md" +keywords = ["mem", "offset", "offset_of", "offsetof"] +categories = ["no-std"] +license = "MIT" +repository = "https://github.com/Gilnaa/memoffset" +[build-dependencies.rustc_version] +version = "0.2.3" diff --git a/third_party/rust/memoffset-0.5.1/LICENSE b/third_party/rust/memoffset-0.5.1/LICENSE new file mode 100644 index 0000000000..61f608134a --- /dev/null +++ b/third_party/rust/memoffset-0.5.1/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2017 Gilad Naaman + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE.
\ No newline at end of file diff --git a/third_party/rust/memoffset-0.5.1/README.md b/third_party/rust/memoffset-0.5.1/README.md new file mode 100644 index 0000000000..9b64e87b3a --- /dev/null +++ b/third_party/rust/memoffset-0.5.1/README.md @@ -0,0 +1,54 @@ +# memoffset # + +[![](http://meritbadge.herokuapp.com/memoffset)](https://crates.io/crates/memoffset) + +C-Like `offset_of` functionality for Rust structs. + +Introduces the following macros: + * `offset_of!` for obtaining the offset of a member of a struct. + * `span_of!` for obtaining the range that a field, or fields, span. + +`memoffset` works under `no_std` environments. + +## Usage ## +Add the following dependency to your `Cargo.toml`: + +```toml +[dependencies] +memoffset = "0.3" +``` + +Versions ">= 0.3" can be used in a constant expression context (though not in a `const fn`), +but require a rust version greater than or equal to 1.33. +These versions will compile fine with rustc versions greater or equal to 1.19, but will +lack support for constant expression. + +If you wish to use an older rustc version, lock your dependency to "0.2" + +Add the following lines at the top of your `main.rs` or `lib.rs` files. + +```rust +#[macro_use] +extern crate memoffset; +``` + +## Examples ## +```rust +#[repr(C, packed)] +struct Foo { + a: u32, + b: u32, + c: [u8; 5], + d: u32, +} + +assert_eq!(offset_of!(Foo, b), 4); +assert_eq!(offset_of!(Foo, c[3]), 11); + +assert_eq!(span_of!(Foo, a), 0..4); +assert_eq!(span_of!(Foo, a .. c), 0..8); +assert_eq!(span_of!(Foo, a .. c[1]), 0..9); +assert_eq!(span_of!(Foo, a ..= c[1]), 0..10); +assert_eq!(span_of!(Foo, ..= d), 0..14); +assert_eq!(span_of!(Foo, b ..), 4..17); +``` diff --git a/third_party/rust/memoffset-0.5.1/build.rs b/third_party/rust/memoffset-0.5.1/build.rs new file mode 100644 index 0000000000..89638e93e7 --- /dev/null +++ b/third_party/rust/memoffset-0.5.1/build.rs @@ -0,0 +1,12 @@ +extern crate rustc_version; +use rustc_version::{version, Version}; + +fn main() { + // Assert we haven't travelled back in time + assert!(version().unwrap().major >= 1); + + // Check for a minimum version + if version().unwrap() >= Version::parse("1.36.0").unwrap() { + println!("cargo:rustc-cfg=memoffset_maybe_uninit"); + } +} diff --git a/third_party/rust/memoffset-0.5.1/src/lib.rs b/third_party/rust/memoffset-0.5.1/src/lib.rs new file mode 100644 index 0000000000..61fc5872c0 --- /dev/null +++ b/third_party/rust/memoffset-0.5.1/src/lib.rs @@ -0,0 +1,76 @@ +// Copyright (c) 2017 Gilad Naaman +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +//! A crate used for calculating offsets of struct members and their spans. +//! +//! Some of the funcationality of the crate makes no sense when used along with structs that +//! are not `#[repr(C, packed)]`, but it is up to the user to make sure that they are. +//! +//! This functionality should work for `const`s but presently doesn't work on `const fn`. Storing a +//! value in a const and then returning it from a `const fn` should workaround most cases. +//! +//! ## Examples +//! ``` +//! #[macro_use] +//! extern crate memoffset; +//! +//! #[repr(C, packed)] +//! struct HelpMeIAmTrappedInAStructFactory { +//! help_me_before_they_: [u8; 15], +//! a: u32 +//! } +//! +//! fn main() { +//! assert_eq!(offset_of!(HelpMeIAmTrappedInAStructFactory, a), 15); +//! assert_eq!(span_of!(HelpMeIAmTrappedInAStructFactory, a), 15..19); +//! assert_eq!(span_of!(HelpMeIAmTrappedInAStructFactory, help_me_before_they_ .. a), 0..15); +//! } +//! ``` +//! +//! This functionality can be useful, for example, for checksum calculations: +//! +//! ```ignore +//! #[repr(C, packed)] +//! struct Message { +//! header: MessageHeader, +//! fragment_index: u32, +//! fragment_count: u32, +//! payload: [u8; 1024], +//! checksum: u16 +//! } +//! +//! let checksum_range = &raw[span_of!(Message, header..checksum)]; +//! let checksum = crc16(checksum_range); +//! ``` + +#![no_std] + +// This `use` statement enables the macros to use `$crate::mem`. +// Doing this enables this crate to function under both std and no-std crates. +#[doc(hidden)] +pub use core::mem; + +#[doc(hidden)] +pub use core::ptr; + +#[macro_use] +mod offset_of; +#[macro_use] +mod span_of; diff --git a/third_party/rust/memoffset-0.5.1/src/offset_of.rs b/third_party/rust/memoffset-0.5.1/src/offset_of.rs new file mode 100644 index 0000000000..82a90d2c96 --- /dev/null +++ b/third_party/rust/memoffset-0.5.1/src/offset_of.rs @@ -0,0 +1,135 @@ +// Copyright (c) 2017 Gilad Naaman +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +/// Macro to create a local `base_ptr` raw pointer of the given type, avoiding UB as +/// much as is possible currently. +#[cfg(memoffset_maybe_uninit)] +#[macro_export] +#[doc(hidden)] +macro_rules! _memoffset__let_base_ptr { + ($name:ident, $type:tt) => { + // No UB here, and the pointer does not dangle, either. + // But we have to make sure that `uninit` lives long enough, + // so it has to be in the same scope as `$name`. That's why + // `let_base_ptr` declares a variable (several, actually) + // instad of returning one. + let uninit = $crate::mem::MaybeUninit::<$type>::uninit(); + let $name = uninit.as_ptr(); + }; +} +#[cfg(not(memoffset_maybe_uninit))] +#[macro_export] +#[doc(hidden)] +macro_rules! _memoffset__let_base_ptr { + ($name:ident, $type:tt) => { + // No UB right here, but we will later offset into a field + // of this pointer, and that is UB when the pointer is dangling. + let non_null = $crate::ptr::NonNull::<$type>::dangling(); + let $name = non_null.as_ptr() as *const $type; + }; +} + +/// Deref-coercion protection macro. +#[macro_export] +#[doc(hidden)] +macro_rules! _memoffset__field_check { + ($type:tt, $field:tt) => { + // Make sure the field actually exists. This line ensures that a + // compile-time error is generated if $field is accessed through a + // Deref impl. + let $type { $field: _, .. }; + }; +} + +/// Calculates the offset of the specified field from the start of the struct. +/// +/// ## Examples +/// ``` +/// #[macro_use] +/// extern crate memoffset; +/// +/// #[repr(C, packed)] +/// struct Foo { +/// a: u32, +/// b: u64, +/// c: [u8; 5] +/// } +/// +/// fn main() { +/// assert_eq!(offset_of!(Foo, a), 0); +/// assert_eq!(offset_of!(Foo, b), 4); +/// } +/// ``` +#[macro_export(local_inner_macros)] +macro_rules! offset_of { + ($parent:tt, $field:tt) => {{ + _memoffset__field_check!($parent, $field); + + // Get a base pointer. + _memoffset__let_base_ptr!(base_ptr, $parent); + // Get the field address. This is UB because we are creating a reference to + // the uninitialized field. + #[allow(unused_unsafe)] // for when the macro is used in an unsafe block + let field_ptr = unsafe { &(*base_ptr).$field as *const _ }; + let offset = (field_ptr as usize) - (base_ptr as usize); + offset + }}; +} + +#[cfg(test)] +mod tests { + #[test] + fn offset_simple() { + #[repr(C)] + struct Foo { + a: u32, + b: [u8; 2], + c: i64, + } + + assert_eq!(offset_of!(Foo, a), 0); + assert_eq!(offset_of!(Foo, b), 4); + assert_eq!(offset_of!(Foo, c), 8); + } + + #[test] + #[cfg(not(miri))] // this creates unaligned references + fn offset_simple_packed() { + #[repr(C, packed)] + struct Foo { + a: u32, + b: [u8; 2], + c: i64, + } + + assert_eq!(offset_of!(Foo, a), 0); + assert_eq!(offset_of!(Foo, b), 4); + assert_eq!(offset_of!(Foo, c), 6); + } + + #[test] + fn tuple_struct() { + #[repr(C)] + struct Tup(i32, i32); + + assert_eq!(offset_of!(Tup, 0), 0); + assert_eq!(offset_of!(Tup, 1), 4); + } +} diff --git a/third_party/rust/memoffset-0.5.1/src/span_of.rs b/third_party/rust/memoffset-0.5.1/src/span_of.rs new file mode 100644 index 0000000000..c48a4569b4 --- /dev/null +++ b/third_party/rust/memoffset-0.5.1/src/span_of.rs @@ -0,0 +1,268 @@ +// Copyright (c) 2017 Gilad Naaman +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +/// Reexport for `local_inner_macros`; see +/// <https://doc.rust-lang.org/edition-guide/rust-2018/macros/macro-changes.html#macros-using-local_inner_macros>. +#[doc(hidden)] +#[macro_export] +macro_rules! _memoffset__compile_error { + ($($inner:tt)*) => { + compile_error! { $($inner)* } + } +} + +/// Produces a range instance representing the sub-slice containing the specified member. +/// +/// This macro provides 2 forms of differing functionalities. +/// +/// The first form is identical to the appearance of the `offset_of!` macro. +/// +/// ```ignore +/// span_of!(Struct, member) +/// ``` +/// +/// The second form of `span_of!` returns a sub-slice which starts at one field, and ends at another. +/// The general pattern of this form is: +/// +/// ```ignore +/// // Exclusive +/// span_of!(Struct, member_a .. member_b) +/// // Inclusive +/// span_of!(Struct, member_a ..= member_b) +/// +/// // Open-ended ranges +/// span_of!(Struct, .. end) +/// span_of!(Struct, start ..) +/// ``` +/// +/// *Note*: +/// This macro uses recursion in order to resolve the range expressions, so there is a limit to +/// the complexity of the expression. +/// In order to raise the limit, the compiler's recursion limit should be lifted. +/// +/// ## Examples +/// ``` +/// #[macro_use] +/// extern crate memoffset; +/// +/// #[repr(C)] +/// struct Florp { +/// a: u32 +/// } +/// +/// #[repr(C)] +/// struct Blarg { +/// x: [u32; 2], +/// y: [u8; 56], +/// z: Florp, +/// egg: [[u8; 4]; 4] +/// } +/// +/// fn main() { +/// assert_eq!(0..84, span_of!(Blarg, ..)); +/// assert_eq!(0..8, span_of!(Blarg, .. y)); +/// assert_eq!(0..64, span_of!(Blarg, ..= y)); +/// assert_eq!(0..8, span_of!(Blarg, x)); +/// assert_eq!(8..84, span_of!(Blarg, y ..)); +/// assert_eq!(0..8, span_of!(Blarg, x .. y)); +/// assert_eq!(0..64, span_of!(Blarg, x ..= y)); +/// } +/// ``` +#[macro_export(local_inner_macros)] +macro_rules! span_of { + (@helper $root:ident, [] ..=) => { + _memoffset__compile_error!("Expected a range, found '..='") + }; + (@helper $root:ident, [] ..) => { + _memoffset__compile_error!("Expected a range, found '..'") + }; + // Lots of UB due to taking references to uninitialized fields! But that can currently + // not be avoided. + // No explicit begin for range. + (@helper $root:ident, $parent:tt, [] ..) => {{ + ($root as usize, + $root as usize + $crate::mem::size_of_val(&(*$root))) + }}; + (@helper $root:ident, $parent:tt, [] ..= $field:tt) => {{ + _memoffset__field_check!($parent, $field); + ($root as usize, + &(*$root).$field as *const _ as usize + $crate::mem::size_of_val(&(*$root).$field)) + }}; + (@helper $root:ident, $parent:tt, [] .. $field:tt) => {{ + _memoffset__field_check!($parent, $field); + ($root as usize, &(*$root).$field as *const _ as usize) + }}; + // Explicit begin and end for range. + (@helper $root:ident, $parent:tt, # $begin:tt [] ..= $end:tt) => {{ + _memoffset__field_check!($parent, $begin); + _memoffset__field_check!($parent, $end); + (&(*$root).$begin as *const _ as usize, + &(*$root).$end as *const _ as usize + $crate::mem::size_of_val(&(*$root).$end)) + }}; + (@helper $root:ident, $parent:tt, # $begin:tt [] .. $end:tt) => {{ + _memoffset__field_check!($parent, $begin); + _memoffset__field_check!($parent, $end); + (&(*$root).$begin as *const _ as usize, + &(*$root).$end as *const _ as usize) + }}; + // No explicit end for range. + (@helper $root:ident, $parent:tt, # $begin:tt [] ..) => {{ + _memoffset__field_check!($parent, $begin); + (&(*$root).$begin as *const _ as usize, + $root as usize + $crate::mem::size_of_val(&*$root)) + }}; + (@helper $root:ident, $parent:tt, # $begin:tt [] ..=) => {{ + _memoffset__compile_error!( + "Found inclusive range to the end of a struct. Did you mean '..' instead of '..='?") + }}; + // Just one field. + (@helper $root:ident, $parent:tt, # $begin:tt []) => {{ + _memoffset__field_check!($parent, $begin); + (&(*$root).$begin as *const _ as usize, + &(*$root).$begin as *const _ as usize + $crate::mem::size_of_val(&(*$root).$begin)) + }}; + // Parsing. + (@helper $root:ident, $parent:tt, $(# $begin:tt)+ [] $tt:tt $($rest:tt)*) => {{ + span_of!(@helper $root, $parent, $(#$begin)* #$tt [] $($rest)*) + }}; + (@helper $root:ident, $parent:tt, [] $tt:tt $($rest:tt)*) => {{ + span_of!(@helper $root, $parent, #$tt [] $($rest)*) + }}; + + // Entry point. + ($sty:tt, $($exp:tt)+) => ({ + unsafe { + // Get a base pointer. + _memoffset__let_base_ptr!(root, $sty); + let base = root as usize; + let (begin, end) = span_of!(@helper root, $sty, [] $($exp)*); + begin-base..end-base + } + }); +} + +#[cfg(test)] +mod tests { + use core::mem; + + #[test] + fn span_simple() { + #[repr(C)] + struct Foo { + a: u32, + b: [u8; 2], + c: i64, + } + + assert_eq!(span_of!(Foo, a), 0..4); + assert_eq!(span_of!(Foo, b), 4..6); + assert_eq!(span_of!(Foo, c), 8..8 + 8); + } + + #[test] + #[cfg(not(miri))] // this creates unaligned references + fn span_simple_packed() { + #[repr(C, packed)] + struct Foo { + a: u32, + b: [u8; 2], + c: i64, + } + + assert_eq!(span_of!(Foo, a), 0..4); + assert_eq!(span_of!(Foo, b), 4..6); + assert_eq!(span_of!(Foo, c), 6..6 + 8); + } + + #[test] + fn span_forms() { + #[repr(C)] + struct Florp { + a: u32, + } + + #[repr(C)] + struct Blarg { + x: u64, + y: [u8; 56], + z: Florp, + egg: [[u8; 4]; 5], + } + + // Love me some brute force + assert_eq!(0..8, span_of!(Blarg, x)); + assert_eq!(64..68, span_of!(Blarg, z)); + assert_eq!(68..mem::size_of::<Blarg>(), span_of!(Blarg, egg)); + + assert_eq!(8..64, span_of!(Blarg, y..z)); + assert_eq!(0..64, span_of!(Blarg, x..=y)); + } + + #[test] + fn ig_test() { + #[repr(C)] + struct Member { + foo: u32, + } + + #[repr(C)] + struct Test { + x: u64, + y: [u8; 56], + z: Member, + egg: [[u8; 4]; 4], + } + + assert_eq!(span_of!(Test, ..x), 0..0); + assert_eq!(span_of!(Test, ..=x), 0..8); + assert_eq!(span_of!(Test, ..y), 0..8); + assert_eq!(span_of!(Test, ..=y), 0..64); + assert_eq!(span_of!(Test, ..z), 0..64); + assert_eq!(span_of!(Test, ..=z), 0..68); + assert_eq!(span_of!(Test, ..egg), 0..68); + assert_eq!(span_of!(Test, ..=egg), 0..84); + assert_eq!(span_of!(Test, ..), 0..mem::size_of::<Test>()); + assert_eq!( + span_of!(Test, x..), + offset_of!(Test, x)..mem::size_of::<Test>() + ); + assert_eq!( + span_of!(Test, y..), + offset_of!(Test, y)..mem::size_of::<Test>() + ); + + assert_eq!( + span_of!(Test, z..), + offset_of!(Test, z)..mem::size_of::<Test>() + ); + assert_eq!( + span_of!(Test, egg..), + offset_of!(Test, egg)..mem::size_of::<Test>() + ); + assert_eq!( + span_of!(Test, x..y), + offset_of!(Test, x)..offset_of!(Test, y) + ); + assert_eq!( + span_of!(Test, x..=y), + offset_of!(Test, x)..offset_of!(Test, y) + mem::size_of::<[u8; 56]>() + ); + } +} |