190 lines
5.2 KiB
Rust
190 lines
5.2 KiB
Rust
// 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 {}
|