Lines Matching +full:test +full:- +full:docs
1 // SPDX-License-Identifier: (BSD-2-Clause OR Apache-2.0) OR MIT
5 // Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
6 // <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
7 // license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
11 //! Utilities used by macros and by `zerocopy-derive`.
14 //! by `zerocopy-derive` so that they can be compiled once rather than
22 // FIXME(#29), FIXME(https://github.com/rust-lang/rust/issues/69835): Remove
68 // to `StaticPaddingFree` or something - or introduce a third trait with that
88 // FIXME(#29), FIXME(https://github.com/rust-lang/rust/issues/69835): Remove
101 // FIXME(#29), FIXME(https://github.com/rust-lang/rust/issues/69835): Remove
110 // - `ptr` is derived from a Rust reference, which is guaranteed to be
111 // non-null.
112 // - `ptr` is derived from an `&Aligned64kAllocation`, which has size and
115 // - `ptr` is derived from a Rust reference, which is guaranteed to have
118 // FIXME(#429): Once `NonNull::new_unchecked` docs document that it
119 // preserves provenance, cite those docs.
131 // FIXME(#29), FIXME(https://github.com/rust-lang/rust/issues/69835): Remove
147 // - If `$ty` is `Sized`, `size_of_val_raw` is always safe to call.
148 // - Otherwise:
149 // - If `$ty` is not a slice DST, this pointer conversion will
152 // - If `$ty` is a slice DST, we have constructed `zero_elems` to
154 // docs, "For the special case where the dynamic tail length is
157 // [1] https://doc.rust-lang.org/nightly/std/mem/fn.size_of_val_raw.html
172 // - Thanks to the preceding `assert!`, we know that the value with zero
176 // is guaranteed to remain in-bounds of its allocation.
177 // - Because the minimum size is no larger than `_64K` bytes, and
183 // - As required by `addr_of!`, we do not write through `field`.
189 // [1] Per https://doc.rust-lang.org/reference/type-layout.html:
193 // [2] https://github.com/rust-lang/reference/pull/1387
198 // - Both `ptr` and `field` are derived from the same allocated object.
199 // - By the preceding safety comment, `field` is in bounds of that
201 // - The distance, in bytes, between `ptr` and `field` is required to be
204 // - The distance, in bytes, cannot overflow `isize`. This is guaranteed
207 // - The distance being in-bounds cannot rely on wrapping around the
211 // [1] FIXME(#429), FIXME(https://github.com/rust-lang/rust/pull/116675):
229 // FIXME(#29), FIXME(https://github.com/rust-lang/rust/issues/69835): Remove
237 // guaranteed [1] to begin with the single-byte layout for `_byte`,
240 // correctly-align the entire struct.
254 // [1]: https://doc.rust-lang.org/nomicon/other-reprs.html#reprc
308 pub const fn size_of<T: Sized + ?core::marker::Sized>() -> usize { in size_of()
327 /// compiler has decided to add. Structs with well-defined representations (such
338 … $crate::util::macro_util::size_of::<$t>() - (0 $(+ $crate::util::macro_util::size_of::<$ts>())*)
380 /// compiler has decided to add. Unions with well-defined representations (such
393 …let padding = $crate::util::macro_util::size_of::<$t>() - $crate::util::macro_util::size_of::<$ts>…
405 /// square-bracket-delimited variant. `$t` must be an enum, or else
416 /// [1]: https://doc.rust-lang.org/1.81.0/reference/type-layout.html#reprc-enums-with-fields
417 /// [2]: https://doc.rust-lang.org/1.81.0/reference/type-layout.html#primitive-representation-of-en…
432 - (
472 /// a hash collision (very unlikely given the <= 16-byte special case), we can
475 /// expensive and higher-quality hash functions if need be.
479 pub const fn hash_name(name: &str) -> i128 { in hash_name()
500 // than normal 64-bit FxHasher. in hash_name()
505 // concatenated back-to-back. in hash_name()
519 /// `try_transmute` may either produce a post-monomorphization error or a panic
525 pub fn try_transmute<Src, Dst>(src: Src) -> Result<Dst, ValidityError<Src, Dst>> in try_transmute()
542 // `ptr` is used to mutate its referent (which it actually can't be - it's in try_transmute()
547 // bit-valid for `Dst`. `ptr` points to `mu_dst`, and no intervening in try_transmute()
548 // operations have mutated it, so it is a bit-valid `Dst`. in try_transmute()
554 // modified, so it is still bit-valid. in try_transmute()
564 fn try_transmute_ref(self) -> Result<&'a Self::Dst, ValidityError<&'a Self::Src, Self::Dst>> in try_transmute_ref()
593 ) -> Result< in try_transmute_ref()
625 ) -> Result<&'a mut Self::Dst, ValidityError<&'a mut Self::Src, Self::Dst>> in try_transmute_mut()
654 ) -> Result< in try_transmute_mut()
690 // without breaking backwards-compatibility (on v0.8.x) with the old
698 pub const fn new(src: Src) -> Self { in new()
709 pub const fn transmute_ref_inference_helper(self) -> &'a Dst { in transmute_ref_inference_helper()
717 /// - `Src: IntoBytes + Immutable`
718 /// - `Dst: FromBytes + Immutable`
723 /// - `mem::size_of::<Dst>() == mem::size_of::<Src>()`
724 /// - `mem::align_of::<Dst>() <= mem::align_of::<Src>()`
727 pub const unsafe fn transmute_ref(self) -> &'a Dst { in transmute_ref()
734 // - We know that it is sound to view the target type of the input in transmute_ref()
738 // - We know that there are no `UnsafeCell`s, and thus we don't have to in transmute_ref()
741 // - The caller has guaranteed that alignment is not increased. in transmute_ref()
742 // - We know that the returned lifetime will not outlive the input in transmute_ref()
754 pub fn try_transmute_ref(self) -> Result<&'a Dst, ValidityError<&'a Src, Dst>> in try_transmute_ref()
795 pub fn transmute_mut_inference_helper(self) -> &'a mut Dst { in transmute_mut_inference_helper()
807 /// - `mem::size_of::<Dst>() == mem::size_of::<Src>()`
808 /// - `mem::align_of::<Dst>() <= mem::align_of::<Src>()`
811 pub fn transmute_mut(self) -> &'a mut Dst in transmute_mut()
822 // - We know that it is sound to view the target type of the input in transmute_mut()
824 // (`Dst`) and vice-versa because `Src: FromBytes + IntoBytes`, `Dst: in transmute_mut()
827 // - We asserted above that alignment will not increase. in transmute_mut()
828 // - We know that the returned lifetime will not outlive the input in transmute_mut()
834 pub fn try_transmute_mut(self) -> Result<&'a mut Dst, ValidityError<&'a mut Src, Dst>> in try_transmute_mut()
866 fn transmute_ref(self) -> &'a Self::Dst; in transmute_ref()
877 fn transmute_ref(self) -> &'a Dst { in transmute_ref()
889 // validly-aligned for `Src`, it is also validly-aligned for `Dst`. in transmute_ref()
899 fn transmute_mut(self) -> &'a mut Self::Dst; in transmute_mut()
910 fn transmute_mut(self) -> &'a mut Dst { in transmute_mut()
922 // validly-aligned for `Src`, it is also validly-aligned for `Dst`. in transmute_mut()
932 pub const fn must_use<T>(t: T) -> T { in must_use()
937 // fixed or we update to a semver-breaking version (as of this writing, 0.8.0)
940 // [1] https://github.com/obi1kenobi/cargo-semver-checks/issues/573
949 #[cfg(test)]
960 // FIXME(#29), FIXME(https://github.com/rust-lang/rust/issues/69835):
963 #[test]
967 macro_rules! test { in test_trailing_field_offset() macro
970 … struct Test($(#[allow(dead_code)] $ts,)* #[allow(dead_code)] $trailing_field_ty); in test_trailing_field_offset()
971 assert_eq!(test!(@offset $($ts),* ; $trailing_field_ty), $expect); in test_trailing_field_offset()
974 test!(#[$cfg] ($($ts),* ; $trailing_field_ty) => $expect); in test_trailing_field_offset()
975 test!($(#[$cfgs])* ($($ts),* ; $trailing_field_ty) => $expect); in test_trailing_field_offset()
977 (@offset ; $_trailing:ty) => { trailing_field_offset!(Test, 0) }; in test_trailing_field_offset()
978 (@offset $_t:ty ; $_trailing:ty) => { trailing_field_offset!(Test, 1) }; in test_trailing_field_offset()
981 test!(#[repr(C)] #[repr(transparent)] #[repr(packed)](; u8) => Some(0)); in test_trailing_field_offset()
982 test!(#[repr(C)] #[repr(transparent)] #[repr(packed)](; [u8]) => Some(0)); in test_trailing_field_offset()
983 test!(#[repr(C)] #[repr(C, packed)] (u8; u8) => Some(1)); in test_trailing_field_offset()
984 test!(#[repr(C)] (; AU64) => Some(0)); in test_trailing_field_offset()
985 test!(#[repr(C)] (; [AU64]) => Some(0)); in test_trailing_field_offset()
986 test!(#[repr(C)] (u8; AU64) => Some(8)); in test_trailing_field_offset()
987 test!(#[repr(C)] (u8; [AU64]) => Some(8)); in test_trailing_field_offset()
998 test!(#[repr(C)] (; Nested<u8, AU64>) => Some(0)); in test_trailing_field_offset()
999 test!(#[repr(C)] (; Nested<u8, [AU64]>) => Some(0)); in test_trailing_field_offset()
1000 test!(#[repr(C)] (u8; Nested<u8, AU64>) => Some(8)); in test_trailing_field_offset()
1001 test!(#[repr(C)] (u8; Nested<u8, [AU64]>) => Some(8)); in test_trailing_field_offset()
1003 // Test that `packed(N)` limits the offset of the trailing field. in test_trailing_field_offset()
1004 test!(#[repr(C, packed( 1))] (u8; elain::Align< 2>) => Some( 1)); in test_trailing_field_offset()
1005 test!(#[repr(C, packed( 2))] (u8; elain::Align< 4>) => Some( 2)); in test_trailing_field_offset()
1006 test!(#[repr(C, packed( 4))] (u8; elain::Align< 8>) => Some( 4)); in test_trailing_field_offset()
1007 test!(#[repr(C, packed( 8))] (u8; elain::Align< 16>) => Some( 8)); in test_trailing_field_offset()
1008 test!(#[repr(C, packed( 16))] (u8; elain::Align< 32>) => Some( 16)); in test_trailing_field_offset()
1009 test!(#[repr(C, packed( 32))] (u8; elain::Align< 64>) => Some( 32)); in test_trailing_field_offset()
1010 test!(#[repr(C, packed( 64))] (u8; elain::Align< 128>) => Some( 64)); in test_trailing_field_offset()
1011 test!(#[repr(C, packed( 128))] (u8; elain::Align< 256>) => Some( 128)); in test_trailing_field_offset()
1012 test!(#[repr(C, packed( 256))] (u8; elain::Align< 512>) => Some( 256)); in test_trailing_field_offset()
1013 test!(#[repr(C, packed( 512))] (u8; elain::Align< 1024>) => Some( 512)); in test_trailing_field_offset()
1014 test!(#[repr(C, packed( 1024))] (u8; elain::Align< 2048>) => Some( 1024)); in test_trailing_field_offset()
1015 test!(#[repr(C, packed( 2048))] (u8; elain::Align< 4096>) => Some( 2048)); in test_trailing_field_offset()
1016 test!(#[repr(C, packed( 4096))] (u8; elain::Align< 8192>) => Some( 4096)); in test_trailing_field_offset()
1017 test!(#[repr(C, packed( 8192))] (u8; elain::Align< 16384>) => Some( 8192)); in test_trailing_field_offset()
1018 test!(#[repr(C, packed( 16384))] (u8; elain::Align< 32768>) => Some( 16384)); in test_trailing_field_offset()
1019 test!(#[repr(C, packed( 32768))] (u8; elain::Align< 65536>) => Some( 32768)); in test_trailing_field_offset()
1020 test!(#[repr(C, packed( 65536))] (u8; elain::Align< 131072>) => Some( 65536)); in test_trailing_field_offset()
1022 test!(#[repr(C, packed( 131072))] (u8; elain::Align< 262144>) => Some( 131072)); in test_trailing_field_offset()
1023 test!(#[repr(C, packed( 262144))] (u8; elain::Align< 524288>) => Some( 262144)); in test_trailing_field_offset()
1024 test!(#[repr(C, packed( 524288))] (u8; elain::Align< 1048576>) => Some( 524288)); in test_trailing_field_offset()
1025 test!(#[repr(C, packed( 1048576))] (u8; elain::Align< 2097152>) => Some( 1048576)); in test_trailing_field_offset()
1026 test!(#[repr(C, packed( 2097152))] (u8; elain::Align< 4194304>) => Some( 2097152)); in test_trailing_field_offset()
1027 test!(#[repr(C, packed( 4194304))] (u8; elain::Align< 8388608>) => Some( 4194304)); in test_trailing_field_offset()
1028 test!(#[repr(C, packed( 8388608))] (u8; elain::Align< 16777216>) => Some( 8388608)); in test_trailing_field_offset()
1029 test!(#[repr(C, packed( 16777216))] (u8; elain::Align< 33554432>) => Some( 16777216)); in test_trailing_field_offset()
1030 test!(#[repr(C, packed( 33554432))] (u8; elain::Align< 67108864>) => Some( 33554432)); in test_trailing_field_offset()
1031 test!(#[repr(C, packed( 67108864))] (u8; elain::Align< 33554432>) => Some( 67108864)); in test_trailing_field_offset()
1032 test!(#[repr(C, packed( 33554432))] (u8; elain::Align<134217728>) => Some( 33554432)); in test_trailing_field_offset()
1033 test!(#[repr(C, packed(134217728))] (u8; elain::Align<268435456>) => Some(134217728)); in test_trailing_field_offset()
1034 test!(#[repr(C, packed(268435456))] (u8; elain::Align<268435456>) => Some(268435456)); in test_trailing_field_offset()
1037 // Test that `align(N)` does not limit the offset of the trailing field. in test_trailing_field_offset()
1038 test!(#[repr(C, align( 1))] (u8; elain::Align< 2>) => Some( 2)); in test_trailing_field_offset()
1039 test!(#[repr(C, align( 2))] (u8; elain::Align< 4>) => Some( 4)); in test_trailing_field_offset()
1040 test!(#[repr(C, align( 4))] (u8; elain::Align< 8>) => Some( 8)); in test_trailing_field_offset()
1041 test!(#[repr(C, align( 8))] (u8; elain::Align< 16>) => Some( 16)); in test_trailing_field_offset()
1042 test!(#[repr(C, align( 16))] (u8; elain::Align< 32>) => Some( 32)); in test_trailing_field_offset()
1043 test!(#[repr(C, align( 32))] (u8; elain::Align< 64>) => Some( 64)); in test_trailing_field_offset()
1044 test!(#[repr(C, align( 64))] (u8; elain::Align< 128>) => Some( 128)); in test_trailing_field_offset()
1045 test!(#[repr(C, align( 128))] (u8; elain::Align< 256>) => Some( 256)); in test_trailing_field_offset()
1046 test!(#[repr(C, align( 256))] (u8; elain::Align< 512>) => Some( 512)); in test_trailing_field_offset()
1047 test!(#[repr(C, align( 512))] (u8; elain::Align< 1024>) => Some( 1024)); in test_trailing_field_offset()
1048 test!(#[repr(C, align( 1024))] (u8; elain::Align< 2048>) => Some( 2048)); in test_trailing_field_offset()
1049 test!(#[repr(C, align( 2048))] (u8; elain::Align< 4096>) => Some( 4096)); in test_trailing_field_offset()
1050 test!(#[repr(C, align( 4096))] (u8; elain::Align< 8192>) => Some( 8192)); in test_trailing_field_offset()
1051 test!(#[repr(C, align( 8192))] (u8; elain::Align< 16384>) => Some( 16384)); in test_trailing_field_offset()
1052 test!(#[repr(C, align( 16384))] (u8; elain::Align< 32768>) => Some( 32768)); in test_trailing_field_offset()
1053 test!(#[repr(C, align( 32768))] (u8; elain::Align< 65536>) => Some( 65536)); in test_trailing_field_offset()
1055 test!(#[repr(C, align( 65536))] (u8; elain::Align< 131072>) => Some( 131072)); in test_trailing_field_offset()
1056 test!(#[repr(C, align( 131072))] (u8; elain::Align< 262144>) => Some( 262144)); in test_trailing_field_offset()
1057 test!(#[repr(C, align( 262144))] (u8; elain::Align< 524288>) => Some( 524288)); in test_trailing_field_offset()
1058 test!(#[repr(C, align( 524288))] (u8; elain::Align< 1048576>) => Some( 1048576)); in test_trailing_field_offset()
1059 test!(#[repr(C, align( 1048576))] (u8; elain::Align< 2097152>) => Some( 2097152)); in test_trailing_field_offset()
1060 test!(#[repr(C, align( 2097152))] (u8; elain::Align< 4194304>) => Some( 4194304)); in test_trailing_field_offset()
1061 test!(#[repr(C, align( 4194304))] (u8; elain::Align< 8388608>) => Some( 8388608)); in test_trailing_field_offset()
1062 test!(#[repr(C, align( 8388608))] (u8; elain::Align< 16777216>) => Some( 16777216)); in test_trailing_field_offset()
1063 test!(#[repr(C, align( 16777216))] (u8; elain::Align< 33554432>) => Some( 33554432)); in test_trailing_field_offset()
1064 test!(#[repr(C, align( 33554432))] (u8; elain::Align< 67108864>) => Some( 67108864)); in test_trailing_field_offset()
1065 test!(#[repr(C, align( 67108864))] (u8; elain::Align< 33554432>) => Some( 33554432)); in test_trailing_field_offset()
1066 test!(#[repr(C, align( 33554432))] (u8; elain::Align<134217728>) => Some(134217728)); in test_trailing_field_offset()
1067 test!(#[repr(C, align(134217728))] (u8; elain::Align<268435456>) => Some(268435456)); in test_trailing_field_offset()
1071 // FIXME(#29), FIXME(https://github.com/rust-lang/rust/issues/69835):
1074 #[test]
1076 // Test that `align_of!` correctly computes the alignment of DSTs. in test_align_of_dst()
1112 #[test]
1114 // Test that casting the variants of enums with signed integer reprs to in test_enum_casts()
1115 // unsigned integers obeys expected signed -> unsigned casting rules. in test_enum_casts()
1119 MinusOne = -1, in test_enum_casts()
1142 #[test]
1144 // Test that, for each provided repr, `struct_padding!` reports the in test_struct_padding()
1146 macro_rules! test { in test_struct_padding() macro
1150 struct Test($($ts),*); in test_struct_padding()
1151 …assert_eq!(struct_padding!(Test, None::<NonZeroUsize>, None::<NonZeroUsize>, [$($ts),*]), $expect); in test_struct_padding()
1154 test!(#[$cfg] ($($ts),*) => $expect); in test_struct_padding()
1155 test!($(#[$cfgs])* ($($ts),*) => $expect); in test_struct_padding()
1159 test!(#[repr(C)] #[repr(transparent)] #[repr(packed)] () => 0); in test_struct_padding()
1160 test!(#[repr(C)] #[repr(transparent)] #[repr(packed)] (u8) => 0); in test_struct_padding()
1161 test!(#[repr(C)] #[repr(transparent)] #[repr(packed)] (u8, ()) => 0); in test_struct_padding()
1162 test!(#[repr(C)] #[repr(packed)] (u8, u8) => 0); in test_struct_padding()
1164 test!(#[repr(C)] (u8, AU64) => 7); in test_struct_padding()
1170 test!(#[repr(packed)] (u8, u64) => 0); in test_struct_padding()
1173 #[test]
1175 // Test that, for each provided repr, `repr_c_struct_padding!` reports in test_repr_c_struct_padding()
1177 macro_rules! test { in test_repr_c_struct_padding() macro
1181 struct Test($($ts),*); in test_repr_c_struct_padding()
1182 …assert_eq!(repr_c_struct_has_padding!(Test, None::<NonZeroUsize>, None::<NonZeroUsize>, [$($ts),*]… in test_repr_c_struct_padding()
1186 // Test static padding in test_repr_c_struct_padding()
1187 test!(() => false); in test_repr_c_struct_padding()
1188 test!(([u8]) => false); in test_repr_c_struct_padding()
1189 test!((u8) => false); in test_repr_c_struct_padding()
1190 test!((u8, [u8]) => false); in test_repr_c_struct_padding()
1191 test!((u8, ()) => false); in test_repr_c_struct_padding()
1192 test!((u8, (), [u8]) => false); in test_repr_c_struct_padding()
1193 test!((u8, u8) => false); in test_repr_c_struct_padding()
1194 test!((u8, u8, [u8]) => false); in test_repr_c_struct_padding()
1196 test!((u8, AU64) => true); in test_repr_c_struct_padding()
1197 test!((u8, AU64, [u8]) => true); in test_repr_c_struct_padding()
1199 // Test dynamic padding in test_repr_c_struct_padding()
1200 test!((AU64, [AU64]) => false); in test_repr_c_struct_padding()
1201 test!((u8, [AU64]) => true); in test_repr_c_struct_padding()
1205 test!((AU64, [AU64]) => false); in test_repr_c_struct_padding()
1206 test!((AU64, [AU32]) => true); in test_repr_c_struct_padding()
1209 #[test]
1211 // Test that, for each provided repr, `union_padding!` reports the in test_union_padding()
1213 macro_rules! test { in test_union_padding() macro
1217 union Test{ $($fs: $ts),* } in test_union_padding()
1218 … assert_eq!(union_padding!(Test, None::<NonZeroUsize>, None::<usize>, [$($ts),*]), $expect); in test_union_padding()
1221 test!(#[$cfg] {$($fs: $ts),*} => $expect); in test_union_padding()
1222 test!($(#[$cfgs])* {$($fs: $ts),*} => $expect); in test_union_padding()
1226 test!(#[repr(C)] #[repr(packed)] {a: u8} => 0); in test_union_padding()
1227 test!(#[repr(C)] #[repr(packed)] {a: u8, b: u8} => 0); in test_union_padding()
1234 test!(#[repr(C)] #[repr(packed)] {a: u8, b: u64} => 7); in test_union_padding()
1237 #[test]
1239 // Test that, for each provided repr, `enum_has_padding!` reports the in test_enum_padding()
1241 macro_rules! test { in test_enum_padding() macro
1243 test!(@case #[repr($disc $(, $c)?)] { $($vs ($($ts),*),)* } => $expect); in test_enum_padding()
1246 test!(@case #[repr($disc $(, $c)?)] #[$cfg] { $($vs ($($ts),*),)* } => $expect); in test_enum_padding()
1247 test!(#[repr($disc $(, $c)?)] $(#[$cfgs])* { $($vs ($($ts),*),)* } => $expect); in test_enum_padding()
1253 enum Test { in test_enum_padding()
1257 … enum_padding!(Test, None::<NonZeroUsize>, None::<NonZeroUsize>, $disc, $([$($ts),*]),*), in test_enum_padding()
1271 test!(#[repr(u8)] #[repr(C)] { in test_enum_padding()
1274 test!(#[repr(u16)] #[repr(C)] { in test_enum_padding()
1278 test!(#[repr(u32)] #[repr(C)] { in test_enum_padding()
1287 test!(#[repr(u8)] { in test_enum_padding()
1290 test!(#[repr(u8)] { in test_enum_padding()
1295 test!(#[repr(u8, C)] { in test_enum_padding()
1298 test!(#[repr(u8, C)] { in test_enum_padding()
1303 test!(#[repr(u8)] #[repr(C)] { in test_enum_padding()
1306 test!(#[repr(u8)] #[repr(C)] { in test_enum_padding()