Source code

Revision control

Copy as Markdown

Other Tools

// Copyright 2024 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.
// Make sure that the derive macros will respect the
// `#[zerocopy(crate = "...")]` attribute when renaming the crate.
// See comment in `include.rs` for why we disable the prelude.
#![no_implicit_prelude]
#![allow(warnings)]
include!("include.rs");
#[test]
fn test_gen_custom_zerocopy() {
#[derive(
imp::ByteEq,
imp::ByteHash,
imp::IntoBytes,
imp::FromBytes,
imp::Unaligned,
imp::Immutable,
imp::KnownLayout,
)]
#[zerocopy(crate = "fake_zerocopy")]
#[repr(packed)]
struct SomeStruct {
a: u16,
b: u32,
}
impl AssertNotZerocopyIntoBytes for SomeStruct {}
impl AssertNotZerocopyFromBytes for SomeStruct {}
impl AssertNotZerocopyUnaligned for SomeStruct {}
impl AssertNotZerocopyImmutable for SomeStruct {}
impl AssertNotZerocopyKnownLayout for SomeStruct {}
fake_zerocopy::assert::<SomeStruct>();
}
mod fake_zerocopy {
use ::std::{io, ptr::NonNull, unimplemented};
pub use super::imp::*;
pub fn assert<T>()
where
T: IntoBytes + FromBytes + Unaligned + Immutable,
{
}
pub unsafe trait IntoBytes {
fn only_derive_is_allowed_to_implement_this_trait()
where
Self: Sized;
fn as_bytes(&self) -> &[u8]
where
Self: Immutable,
{
unimplemented!()
}
}
pub unsafe trait FromBytes: FromZeros {
fn only_derive_is_allowed_to_implement_this_trait()
where
Self: Sized;
}
pub unsafe trait Unaligned {
fn only_derive_is_allowed_to_implement_this_trait()
where
Self: Sized;
}
pub unsafe trait Immutable {
fn only_derive_is_allowed_to_implement_this_trait()
where
Self: Sized;
}
pub unsafe trait KnownLayout {
fn only_derive_is_allowed_to_implement_this_trait()
where
Self: Sized;
type PointerMetadata: PointerMetadata;
type MaybeUninit: ?Sized + KnownLayout<PointerMetadata = Self::PointerMetadata>;
const LAYOUT: DstLayout;
fn raw_from_ptr_len(bytes: NonNull<u8>, meta: Self::PointerMetadata) -> NonNull<Self>;
fn pointer_to_metadata(ptr: *mut Self) -> Self::PointerMetadata;
}
macro_rules! impl_ty {
($ty:ty $(as $generic:ident)?) => {
unsafe impl$(<$generic: IntoBytes>)? IntoBytes for $ty {
fn only_derive_is_allowed_to_implement_this_trait()
where
Self: Sized,
{
unimplemented!()
}
}
unsafe impl$(<$generic: FromBytes>)? FromBytes for $ty {
fn only_derive_is_allowed_to_implement_this_trait()
where
Self: Sized,
{
unimplemented!()
}
}
unsafe impl$(<$generic: Unaligned>)? Unaligned for $ty {
fn only_derive_is_allowed_to_implement_this_trait()
where
Self: Sized,
{
unimplemented!()
}
}
unsafe impl$(<$generic: Immutable>)? Immutable for $ty {
fn only_derive_is_allowed_to_implement_this_trait()
where
Self: Sized,
{
unimplemented!()
}
}
unsafe impl$(<$generic: KnownLayout>)? KnownLayout for $ty {
fn only_derive_is_allowed_to_implement_this_trait()
where
Self: Sized,
{
unimplemented!()
}
type PointerMetadata = ();
type MaybeUninit = ();
const LAYOUT: DstLayout = DstLayout::new_zst(None);
fn raw_from_ptr_len(
bytes: NonNull<u8>,
meta: Self::PointerMetadata,
) -> NonNull<Self> {
unimplemented!()
}
fn pointer_to_metadata(ptr: *mut Self) -> Self::PointerMetadata {
unimplemented!()
}
}
};
}
impl_ty!(());
impl_ty!(u16);
impl_ty!(u32);
impl_ty!([T] as T);
impl_ty!(::std::mem::MaybeUninit<T> as T);
}
pub trait AssertNotZerocopyIntoBytes {}
impl<T: imp::IntoBytes> AssertNotZerocopyIntoBytes for T {}
pub trait AssertNotZerocopyFromBytes {}
impl<T: imp::FromBytes> AssertNotZerocopyFromBytes for T {}
pub trait AssertNotZerocopyUnaligned {}
impl<T: imp::Unaligned> AssertNotZerocopyUnaligned for T {}
pub trait AssertNotZerocopyImmutable {}
impl<T: imp::Immutable> AssertNotZerocopyImmutable for T {}
pub trait AssertNotZerocopyKnownLayout {}
impl<T: imp::KnownLayout> AssertNotZerocopyKnownLayout for T {}