1#![allow(unknown_lints)]
18#![deny(renamed_and_removed_lints)]
19#![deny(
20 clippy::all,
21 clippy::missing_safety_doc,
22 clippy::multiple_unsafe_ops_per_block,
23 clippy::undocumented_unsafe_blocks
24)]
25#![allow(clippy::type_complexity)]
27#![allow(clippy::uninlined_format_args)]
29#![deny(
30 rustdoc::bare_urls,
31 rustdoc::broken_intra_doc_links,
32 rustdoc::invalid_codeblock_attributes,
33 rustdoc::invalid_html_tags,
34 rustdoc::invalid_rust_codeblocks,
35 rustdoc::missing_crate_level_docs,
36 rustdoc::private_intra_doc_links
37)]
38#![recursion_limit = "128"]
39
40macro_rules! ident {
41 (($fmt:literal $(, $arg:expr)*), $span:expr) => {
42 syn::Ident::new(&format!($fmt $(, crate::util::to_ident_str($arg))*), $span)
43 };
44}
45
46mod derive;
47#[cfg(test)]
48mod output_tests;
49mod repr;
50mod util;
51
52use syn::{DeriveInput, Error};
53
54use crate::util::*;
55
56macro_rules! derive {
80 ($trait:ident => $outer:ident => $inner:path) => {
81 #[proc_macro_derive($trait, attributes(zerocopy))]
82 pub fn $outer(ts: proc_macro::TokenStream) -> proc_macro::TokenStream {
83 let ast = syn::parse_macro_input!(ts as DeriveInput);
84 let ctx = match Ctx::try_from_derive_input(ast) {
85 Ok(ctx) => ctx,
86 Err(e) => return e.into_compile_error().into(),
87 };
88 let ts = $inner(&ctx, Trait::$trait).into_ts();
89 let ts = const_block([Some(ts)]);
93 #[cfg(test)]
94 crate::util::testutil::check_hygiene(ts.clone());
95 ts.into()
96 }
97 };
98}
99
100trait IntoTokenStream {
101 fn into_ts(self) -> proc_macro2::TokenStream;
102}
103
104impl IntoTokenStream for proc_macro2::TokenStream {
105 fn into_ts(self) -> proc_macro2::TokenStream {
106 self
107 }
108}
109
110impl IntoTokenStream for Result<proc_macro2::TokenStream, Error> {
111 fn into_ts(self) -> proc_macro2::TokenStream {
112 match self {
113 Ok(ts) => ts,
114 Err(err) => err.to_compile_error(),
115 }
116 }
117}
118
119derive!(KnownLayout => derive_known_layout => crate::derive::known_layout::derive);
120derive!(Immutable => derive_immutable => crate::derive::derive_immutable);
121derive!(TryFromBytes => derive_try_from_bytes => crate::derive::try_from_bytes::derive_try_from_bytes);
122derive!(FromZeros => derive_from_zeros => crate::derive::from_bytes::derive_from_zeros);
123derive!(FromBytes => derive_from_bytes => crate::derive::from_bytes::derive_from_bytes);
124derive!(IntoBytes => derive_into_bytes => crate::derive::into_bytes::derive_into_bytes);
125derive!(Unaligned => derive_unaligned => crate::derive::unaligned::derive_unaligned);
126derive!(ByteHash => derive_hash => crate::derive::derive_hash);
127derive!(ByteEq => derive_eq => crate::derive::derive_eq);
128derive!(SplitAt => derive_split_at => crate::derive::derive_split_at);
129
130#[deprecated(since = "0.8.0", note = "`FromZeroes` was renamed to `FromZeros`")]
132#[doc(hidden)]
133#[proc_macro_derive(FromZeroes)]
134pub fn derive_from_zeroes(ts: proc_macro::TokenStream) -> proc_macro::TokenStream {
135 derive_from_zeros(ts)
136}
137
138#[deprecated(since = "0.8.0", note = "`AsBytes` was renamed to `IntoBytes`")]
140#[doc(hidden)]
141#[proc_macro_derive(AsBytes)]
142pub fn derive_as_bytes(ts: proc_macro::TokenStream) -> proc_macro::TokenStream {
143 derive_into_bytes(ts)
144}