mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 09:36:22 +02:00
Update our vendored copy of `zerocopy` (and `zerocopy-derive`) to v0.8.54.
It is a very small delta from v0.8.52, and most importantly it resolves
the unexpected lack of inlining [1] which triggered a modpost error
under `CONFIG_CC_OPTIMIZE_FOR_SIZE=y` reported by Alexandre using Gary's
suggestion [2]:
ERROR: modpost: "_RNvMNtCs5wX7wwEUCR9_8zerocopy6layoutNtB2_8SizeInfo24try_to_nonzero_elem_size" [drivers/gpu/nova-core.ko] undefined!
ERROR: modpost: "_RNvNtCs5wX7wwEUCR9_8zerocopy4util18padding_needed_for" [drivers/gpu/nova-core.ko] undefined!
It also resolves `most_traits` being unexpectedly documented [3] that I
reported and adds a missing SPDX license identifier [4] that I requested
to match the kernel version.
The following script may be used to check for the remaining differences:
for path in $(cd rust/zerocopy-derive/ && find . -type f ! -name README.md); do
curl --silent --show-error --location \
https://github.com/google/zerocopy/raw/v0.8.54/zerocopy/zerocopy-derive/src/$path |
git diff --no-index - rust/zerocopy-derive/$path &&
echo $path: OK
done
for path in $(cd rust/zerocopy/ && find . -type f ! -name README.md); do
curl --silent --show-error --location \
https://github.com/google/zerocopy/raw/v0.8.54/zerocopy/$path |
git diff --no-index - rust/zerocopy/$path &&
echo $path: OK
done
Cc: Joshua Liebow-Feeser <joshlf@google.com>
Cc: Jack Wrenn <jswrenn@google.com>
Reported-by: Alexandre Courbot <acourbot@nvidia.com>
Closes: https://lore.kernel.org/rust-for-linux/20260708-zerocopy-export-v1-1-2bfc355853c6@nvidia.com/ [1]
Suggested-by: Gary Guo <gary@garyguo.net>
Link: https://lore.kernel.org/rust-for-linux/DJT6235B3DOV.222XR5O6VHG4M@garyguo.net/ [2]
Link: https://github.com/google/zerocopy/issues/3466 [3]
Link: https://github.com/google/zerocopy/issues/3457 [4]
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Tested-by: Alexandre Courbot <acourbot@nvidia.com>
Reviewed-by: Gary Guo <gary@garyguo.net>
Link: https://patch.msgid.link/20260709211311.142544-1-ojeda@kernel.org
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
181 lines
6.7 KiB
Rust
181 lines
6.7 KiB
Rust
// SPDX-License-Identifier: (BSD-2-Clause OR Apache-2.0) OR MIT
|
|
//
|
|
// Copyright 2019 The Fuchsia Authors
|
|
//
|
|
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
|
|
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
|
|
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
|
|
// This file may not be copied, modified, or distributed except according to
|
|
// those terms.
|
|
|
|
//! Derive macros for [zerocopy]'s traits.
|
|
//!
|
|
//! [zerocopy]: https://docs.rs/zerocopy
|
|
|
|
// Sometimes we want to use lints which were added after our MSRV.
|
|
// `unknown_lints` is `warn` by default and we deny warnings in CI, so without
|
|
// this attribute, any unknown lint would cause a CI failure when testing with
|
|
// our MSRV.
|
|
#![allow(unknown_lints)]
|
|
#![deny(renamed_and_removed_lints)]
|
|
#![deny(
|
|
clippy::all,
|
|
clippy::missing_safety_doc,
|
|
clippy::multiple_unsafe_ops_per_block,
|
|
clippy::undocumented_unsafe_blocks
|
|
)]
|
|
// We defer to own discretion on type complexity.
|
|
#![allow(clippy::type_complexity)]
|
|
// Inlining format args isn't supported on our MSRV.
|
|
#![allow(clippy::uninlined_format_args)]
|
|
#![deny(
|
|
rustdoc::bare_urls,
|
|
rustdoc::broken_intra_doc_links,
|
|
rustdoc::invalid_codeblock_attributes,
|
|
rustdoc::invalid_html_tags,
|
|
rustdoc::invalid_rust_codeblocks,
|
|
rustdoc::missing_crate_level_docs,
|
|
rustdoc::private_intra_doc_links
|
|
)]
|
|
#![recursion_limit = "128"]
|
|
|
|
macro_rules! ident {
|
|
(($fmt:literal $(, $arg:expr)*), $span:expr) => {
|
|
syn::Ident::new(&format!($fmt $(, crate::util::to_ident_str($arg))*), $span)
|
|
};
|
|
}
|
|
|
|
mod derive;
|
|
#[cfg(test)]
|
|
mod output_tests;
|
|
mod repr;
|
|
mod util;
|
|
|
|
use syn::{DeriveInput, Error};
|
|
|
|
use crate::util::*;
|
|
|
|
// FIXME(https://github.com/rust-lang/rust/issues/54140): Some errors could be
|
|
// made better if we could add multiple lines of error output like this:
|
|
//
|
|
// error: unsupported representation
|
|
// --> enum.rs:28:8
|
|
// |
|
|
// 28 | #[repr(transparent)]
|
|
// |
|
|
// help: required by the derive of FromBytes
|
|
//
|
|
// Instead, we have more verbose error messages like "unsupported representation
|
|
// for deriving FromZeros, FromBytes, IntoBytes, or Unaligned on an enum"
|
|
//
|
|
// This will probably require Span::error
|
|
// (https://doc.rust-lang.org/nightly/proc_macro/struct.Span.html#method.error),
|
|
// which is currently unstable. Revisit this once it's stable.
|
|
|
|
/// Defines a derive function named `$outer` which parses its input
|
|
/// `TokenStream` as a `DeriveInput` and then invokes the `$inner` function.
|
|
///
|
|
/// Note that the separate `$outer` parameter is required - proc macro functions
|
|
/// are currently required to live at the crate root, and so the caller must
|
|
/// specify the name in order to avoid name collisions.
|
|
macro_rules! derive {
|
|
($trait:ident => $outer:ident => $inner:path) => {
|
|
#[proc_macro_derive($trait, attributes(zerocopy))]
|
|
pub fn $outer(ts: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
|
let ast = syn::parse_macro_input!(ts as DeriveInput);
|
|
let ctx = match Ctx::try_from_derive_input(ast) {
|
|
Ok(ctx) => ctx,
|
|
Err(e) => return e.into_compile_error().into(),
|
|
};
|
|
let ts = $inner(&ctx, Trait::$trait).into_ts();
|
|
// We wrap in `const_block` as a backstop in case any derive fails
|
|
// to wrap its output in `const_block` (and thus fails to annotate)
|
|
// with the full set of `#[allow(...)]` attributes).
|
|
let ts = const_block([Some(ts)]);
|
|
#[cfg(test)]
|
|
crate::util::testutil::check_hygiene(ts.clone());
|
|
ts.into()
|
|
}
|
|
};
|
|
}
|
|
|
|
trait IntoTokenStream {
|
|
fn into_ts(self) -> proc_macro2::TokenStream;
|
|
}
|
|
|
|
impl IntoTokenStream for proc_macro2::TokenStream {
|
|
fn into_ts(self) -> proc_macro2::TokenStream {
|
|
self
|
|
}
|
|
}
|
|
|
|
impl IntoTokenStream for Result<proc_macro2::TokenStream, Error> {
|
|
fn into_ts(self) -> proc_macro2::TokenStream {
|
|
match self {
|
|
Ok(ts) => ts,
|
|
Err(err) => err.to_compile_error(),
|
|
}
|
|
}
|
|
}
|
|
|
|
derive!(KnownLayout => derive_known_layout => crate::derive::known_layout::derive);
|
|
derive!(Immutable => derive_immutable => crate::derive::derive_immutable);
|
|
derive!(TryFromBytes => derive_try_from_bytes => crate::derive::try_from_bytes::derive_try_from_bytes);
|
|
derive!(FromZeros => derive_from_zeros => crate::derive::from_bytes::derive_from_zeros);
|
|
derive!(FromBytes => derive_from_bytes => crate::derive::from_bytes::derive_from_bytes);
|
|
derive!(IntoBytes => derive_into_bytes => crate::derive::into_bytes::derive_into_bytes);
|
|
derive!(Unaligned => derive_unaligned => crate::derive::unaligned::derive_unaligned);
|
|
derive!(ByteHash => derive_hash => crate::derive::derive_hash);
|
|
derive!(ByteEq => derive_eq => crate::derive::derive_eq);
|
|
derive!(SplitAt => derive_split_at => crate::derive::derive_split_at);
|
|
|
|
#[cfg_attr(not(zerocopy_unstable_linux), doc(hidden))]
|
|
#[proc_macro_derive(most_traits, attributes(zerocopy))]
|
|
pub fn most_traits(ts: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
|
let ast = syn::parse_macro_input!(ts as DeriveInput);
|
|
let ctx = match Ctx::try_from_derive_input(ast) {
|
|
Ok(ctx) => ctx,
|
|
Err(e) => return e.into_compile_error().into(),
|
|
}
|
|
.skip_on_error();
|
|
|
|
// top-level traits for which to attempt a derive
|
|
let derives: [(fn(&Ctx, Trait) -> _, _); 6] = [
|
|
(crate::derive::known_layout::derive, Trait::KnownLayout),
|
|
(crate::derive::derive_immutable, Trait::Immutable),
|
|
(crate::derive::from_bytes::derive_from_bytes, Trait::FromBytes),
|
|
(crate::derive::into_bytes::derive_into_bytes, Trait::IntoBytes),
|
|
(crate::derive::derive_split_at, Trait::SplitAt),
|
|
(crate::derive::unaligned::derive_unaligned, Trait::Unaligned),
|
|
];
|
|
|
|
let mut tokens = proc_macro2::TokenStream::new();
|
|
for (derive, t) in derives {
|
|
tokens.extend(derive(&ctx, t))
|
|
}
|
|
|
|
// We wrap in `const_block` as a backstop in case any derive fails
|
|
// to wrap its output in `const_block` (and thus fails to annotate)
|
|
// with the full set of `#[allow(...)]` attributes).
|
|
let ts = const_block([Some(tokens)]);
|
|
#[cfg(test)]
|
|
crate::util::testutil::check_hygiene(ts.clone());
|
|
ts.into()
|
|
}
|
|
|
|
/// Deprecated: prefer [`FromZeros`] instead.
|
|
#[deprecated(since = "0.8.0", note = "`FromZeroes` was renamed to `FromZeros`")]
|
|
#[doc(hidden)]
|
|
#[proc_macro_derive(FromZeroes)]
|
|
pub fn derive_from_zeroes(ts: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
|
derive_from_zeros(ts)
|
|
}
|
|
|
|
/// Deprecated: prefer [`IntoBytes`] instead.
|
|
#[deprecated(since = "0.8.0", note = "`AsBytes` was renamed to `IntoBytes`")]
|
|
#[doc(hidden)]
|
|
#[proc_macro_derive(AsBytes)]
|
|
pub fn derive_as_bytes(ts: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
|
derive_into_bytes(ts)
|
|
}
|