Vendor things

This commit is contained in:
John Doty 2024-03-08 11:03:01 -08:00
parent 5deceec006
commit 977e3c17e5
19434 changed files with 10682014 additions and 0 deletions

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,44 @@
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
#
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
# to registry (e.g., crates.io) dependencies.
#
# If you are reading this file be aware that the original Cargo.toml
# will likely look very different (and much more reasonable).
# See Cargo.toml.orig for the original contents.
[package]
edition = "2018"
rust-version = "1.60.0"
name = "zerocopy-derive"
version = "0.7.32"
authors = ["Joshua Liebow-Feeser <joshlf@google.com>"]
exclude = [
".*",
"tests/enum_from_bytes.rs",
"tests/ui-nightly/enum_from_bytes_u16_too_few.rs.disabled",
]
description = "Custom derive for traits from the zerocopy crate"
license = "BSD-2-Clause OR Apache-2.0 OR MIT"
repository = "https://github.com/google/zerocopy"
[lib]
proc-macro = true
[dependencies.proc-macro2]
version = "1.0.1"
[dependencies.quote]
version = "1.0.10"
[dependencies.syn]
version = "2.0.31"
[dev-dependencies.static_assertions]
version = "1.1"
[dev-dependencies.trybuild]
version = "=1.0.85"
features = ["diff"]

View file

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2023 The Fuchsia Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View file

@ -0,0 +1,24 @@
Copyright 2019 The Fuchsia Authors.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View file

@ -0,0 +1,26 @@
Copyright 2023 The Fuchsia Authors
Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the
Software without restriction, including without
limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software
is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice
shall be included in all copies or substantial portions
of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

View file

@ -0,0 +1,53 @@
// 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.
use syn::{Data, DataEnum, DataStruct, DataUnion, Type};
pub trait DataExt {
/// Extract the types of all fields. For enums, extract the types of fields
/// from each variant.
fn field_types(&self) -> Vec<&Type>;
}
impl DataExt for Data {
fn field_types(&self) -> Vec<&Type> {
match self {
Data::Struct(strc) => strc.field_types(),
Data::Enum(enm) => enm.field_types(),
Data::Union(un) => un.field_types(),
}
}
}
impl DataExt for DataStruct {
fn field_types(&self) -> Vec<&Type> {
self.fields.iter().map(|f| &f.ty).collect()
}
}
impl DataExt for DataEnum {
fn field_types(&self) -> Vec<&Type> {
self.variants.iter().flat_map(|var| &var.fields).map(|f| &f.ty).collect()
}
}
impl DataExt for DataUnion {
fn field_types(&self) -> Vec<&Type> {
self.fields.named.iter().map(|f| &f.ty).collect()
}
}
pub trait EnumExt {
fn is_c_like(&self) -> bool;
}
impl EnumExt for DataEnum {
fn is_c_like(&self) -> bool {
self.field_types().is_empty()
}
}

View file

@ -0,0 +1,882 @@
// 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::undocumented_unsafe_blocks)]
#![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"]
mod ext;
mod repr;
use {
proc_macro2::Span,
quote::quote,
syn::{
parse_quote, Data, DataEnum, DataStruct, DataUnion, DeriveInput, Error, Expr, ExprLit,
GenericParam, Ident, Lit,
},
};
use {crate::ext::*, crate::repr::*};
// Unwraps a `Result<_, Vec<Error>>`, converting any `Err` value into a
// `TokenStream` and returning it.
macro_rules! try_or_print {
($e:expr) => {
match $e {
Ok(x) => x,
Err(errors) => return print_all_errors(errors).into(),
}
};
}
// TODO(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 FromZeroes, FromBytes, AsBytes, 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.
#[proc_macro_derive(KnownLayout)]
pub fn derive_known_layout(ts: proc_macro::TokenStream) -> proc_macro::TokenStream {
let ast = syn::parse_macro_input!(ts as DeriveInput);
let is_repr_c_struct = match &ast.data {
Data::Struct(..) => {
let reprs = try_or_print!(repr::reprs::<Repr>(&ast.attrs));
if reprs.iter().any(|(_meta, repr)| repr == &Repr::C) {
Some(reprs)
} else {
None
}
}
Data::Enum(..) | Data::Union(..) => None,
};
let fields = ast.data.field_types();
let (require_self_sized, extras) = if let (
Some(reprs),
Some((trailing_field, leading_fields)),
) = (is_repr_c_struct, fields.split_last())
{
let repr_align = reprs
.iter()
.find_map(
|(_meta, repr)| {
if let Repr::Align(repr_align) = repr {
Some(repr_align)
} else {
None
}
},
)
.map(|repr_align| quote!(NonZeroUsize::new(#repr_align as usize)))
.unwrap_or(quote!(None));
let repr_packed = reprs
.iter()
.find_map(|(_meta, repr)| match repr {
Repr::Packed => Some(1),
Repr::PackedN(repr_packed) => Some(*repr_packed),
_ => None,
})
.map(|repr_packed| quote!(NonZeroUsize::new(#repr_packed as usize)))
.unwrap_or(quote!(None));
(
false,
quote!(
// SAFETY: `LAYOUT` accurately describes the layout of `Self`.
// The layout of `Self` is reflected using a sequence of
// invocations of `DstLayout::{new_zst,extend,pad_to_align}`.
// The documentation of these items vows that invocations in
// this manner will acurately describe a type, so long as:
//
// - that type is `repr(C)`,
// - its fields are enumerated in the order they appear,
// - the presence of `repr_align` and `repr_packed` are correctly accounted for.
//
// We respect all three of these preconditions here. This
// expansion is only used if `is_repr_c_struct`, we enumerate
// the fields in order, and we extract the values of `align(N)`
// and `packed(N)`.
const LAYOUT: ::zerocopy::DstLayout = {
use ::zerocopy::macro_util::core_reexport::num::NonZeroUsize;
use ::zerocopy::{DstLayout, KnownLayout};
let repr_align = #repr_align;
let repr_packed = #repr_packed;
DstLayout::new_zst(repr_align)
#(.extend(DstLayout::for_type::<#leading_fields>(), repr_packed))*
.extend(<#trailing_field as KnownLayout>::LAYOUT, repr_packed)
.pad_to_align()
};
// SAFETY:
// - The recursive call to `raw_from_ptr_len` preserves both address and provenance.
// - The `as` cast preserves both address and provenance.
// - `NonNull::new_unchecked` preserves both address and provenance.
#[inline(always)]
fn raw_from_ptr_len(
bytes: ::zerocopy::macro_util::core_reexport::ptr::NonNull<u8>,
elems: usize,
) -> ::zerocopy::macro_util::core_reexport::ptr::NonNull<Self> {
use ::zerocopy::{KnownLayout};
let trailing = <#trailing_field as KnownLayout>::raw_from_ptr_len(bytes, elems);
let slf = trailing.as_ptr() as *mut Self;
// SAFETY: Constructed from `trailing`, which is non-null.
unsafe { ::zerocopy::macro_util::core_reexport::ptr::NonNull::new_unchecked(slf) }
}
),
)
} else {
// For enums, unions, and non-`repr(C)` structs, we require that
// `Self` is sized, and as a result don't need to reason about the
// internals of the type.
(
true,
quote!(
// SAFETY: `LAYOUT` is guaranteed to accurately describe the
// layout of `Self`, because that is the documented safety
// contract of `DstLayout::for_type`.
const LAYOUT: ::zerocopy::DstLayout = ::zerocopy::DstLayout::for_type::<Self>();
// SAFETY: `.cast` preserves address and provenance.
//
// TODO(#429): Add documentation to `.cast` that promises that
// it preserves provenance.
#[inline(always)]
fn raw_from_ptr_len(
bytes: ::zerocopy::macro_util::core_reexport::ptr::NonNull<u8>,
_elems: usize,
) -> ::zerocopy::macro_util::core_reexport::ptr::NonNull<Self> {
bytes.cast::<Self>()
}
),
)
};
match &ast.data {
Data::Struct(strct) => {
let require_trait_bound_on_field_types = if require_self_sized {
RequireBoundedFields::No
} else {
RequireBoundedFields::Trailing
};
// A bound on the trailing field is required, since structs are
// unsized if their trailing field is unsized. Reflecting the layout
// of an usized trailing field requires that the field is
// `KnownLayout`.
impl_block(
&ast,
strct,
Trait::KnownLayout,
require_trait_bound_on_field_types,
require_self_sized,
None,
Some(extras),
)
}
Data::Enum(enm) => {
// A bound on the trailing field is not required, since enums cannot
// currently be unsized.
impl_block(
&ast,
enm,
Trait::KnownLayout,
RequireBoundedFields::No,
true,
None,
Some(extras),
)
}
Data::Union(unn) => {
// A bound on the trailing field is not required, since unions
// cannot currently be unsized.
impl_block(
&ast,
unn,
Trait::KnownLayout,
RequireBoundedFields::No,
true,
None,
Some(extras),
)
}
}
.into()
}
#[proc_macro_derive(FromZeroes)]
pub fn derive_from_zeroes(ts: proc_macro::TokenStream) -> proc_macro::TokenStream {
let ast = syn::parse_macro_input!(ts as DeriveInput);
match &ast.data {
Data::Struct(strct) => derive_from_zeroes_struct(&ast, strct),
Data::Enum(enm) => derive_from_zeroes_enum(&ast, enm),
Data::Union(unn) => derive_from_zeroes_union(&ast, unn),
}
.into()
}
#[proc_macro_derive(FromBytes)]
pub fn derive_from_bytes(ts: proc_macro::TokenStream) -> proc_macro::TokenStream {
let ast = syn::parse_macro_input!(ts as DeriveInput);
match &ast.data {
Data::Struct(strct) => derive_from_bytes_struct(&ast, strct),
Data::Enum(enm) => derive_from_bytes_enum(&ast, enm),
Data::Union(unn) => derive_from_bytes_union(&ast, unn),
}
.into()
}
#[proc_macro_derive(AsBytes)]
pub fn derive_as_bytes(ts: proc_macro::TokenStream) -> proc_macro::TokenStream {
let ast = syn::parse_macro_input!(ts as DeriveInput);
match &ast.data {
Data::Struct(strct) => derive_as_bytes_struct(&ast, strct),
Data::Enum(enm) => derive_as_bytes_enum(&ast, enm),
Data::Union(unn) => derive_as_bytes_union(&ast, unn),
}
.into()
}
#[proc_macro_derive(Unaligned)]
pub fn derive_unaligned(ts: proc_macro::TokenStream) -> proc_macro::TokenStream {
let ast = syn::parse_macro_input!(ts as DeriveInput);
match &ast.data {
Data::Struct(strct) => derive_unaligned_struct(&ast, strct),
Data::Enum(enm) => derive_unaligned_enum(&ast, enm),
Data::Union(unn) => derive_unaligned_union(&ast, unn),
}
.into()
}
const STRUCT_UNION_ALLOWED_REPR_COMBINATIONS: &[&[StructRepr]] = &[
&[StructRepr::C],
&[StructRepr::Transparent],
&[StructRepr::Packed],
&[StructRepr::C, StructRepr::Packed],
];
// A struct is `FromZeroes` if:
// - all fields are `FromZeroes`
fn derive_from_zeroes_struct(ast: &DeriveInput, strct: &DataStruct) -> proc_macro2::TokenStream {
impl_block(ast, strct, Trait::FromZeroes, RequireBoundedFields::Yes, false, None, None)
}
// An enum is `FromZeroes` if:
// - all of its variants are fieldless
// - one of the variants has a discriminant of `0`
fn derive_from_zeroes_enum(ast: &DeriveInput, enm: &DataEnum) -> proc_macro2::TokenStream {
if !enm.is_c_like() {
return Error::new_spanned(ast, "only C-like enums can implement FromZeroes")
.to_compile_error();
}
let has_explicit_zero_discriminant =
enm.variants.iter().filter_map(|v| v.discriminant.as_ref()).any(|(_, e)| {
if let Expr::Lit(ExprLit { lit: Lit::Int(i), .. }) = e {
i.base10_parse::<usize>().ok() == Some(0)
} else {
false
}
});
// If the first variant of an enum does not specify its discriminant, it is set to zero:
// https://doc.rust-lang.org/reference/items/enumerations.html#custom-discriminant-values-for-fieldless-enumerations
let has_implicit_zero_discriminant =
enm.variants.iter().next().map(|v| v.discriminant.is_none()) == Some(true);
if !has_explicit_zero_discriminant && !has_implicit_zero_discriminant {
return Error::new_spanned(
ast,
"FromZeroes only supported on enums with a variant that has a discriminant of `0`",
)
.to_compile_error();
}
impl_block(ast, enm, Trait::FromZeroes, RequireBoundedFields::Yes, false, None, None)
}
// Like structs, unions are `FromZeroes` if
// - all fields are `FromZeroes`
fn derive_from_zeroes_union(ast: &DeriveInput, unn: &DataUnion) -> proc_macro2::TokenStream {
impl_block(ast, unn, Trait::FromZeroes, RequireBoundedFields::Yes, false, None, None)
}
// A struct is `FromBytes` if:
// - all fields are `FromBytes`
fn derive_from_bytes_struct(ast: &DeriveInput, strct: &DataStruct) -> proc_macro2::TokenStream {
impl_block(ast, strct, Trait::FromBytes, RequireBoundedFields::Yes, false, None, None)
}
// An enum is `FromBytes` if:
// - Every possible bit pattern must be valid, which means that every bit
// pattern must correspond to a different enum variant. Thus, for an enum
// whose layout takes up N bytes, there must be 2^N variants.
// - Since we must know N, only representations which guarantee the layout's
// size are allowed. These are `repr(uN)` and `repr(iN)` (`repr(C)` implies an
// implementation-defined size). `usize` and `isize` technically guarantee the
// layout's size, but would require us to know how large those are on the
// target platform. This isn't terribly difficult - we could emit a const
// expression that could call `core::mem::size_of` in order to determine the
// size and check against the number of enum variants, but a) this would be
// platform-specific and, b) even on Rust's smallest bit width platform (32),
// this would require ~4 billion enum variants, which obviously isn't a thing.
fn derive_from_bytes_enum(ast: &DeriveInput, enm: &DataEnum) -> proc_macro2::TokenStream {
if !enm.is_c_like() {
return Error::new_spanned(ast, "only C-like enums can implement FromBytes")
.to_compile_error();
}
let reprs = try_or_print!(ENUM_FROM_BYTES_CFG.validate_reprs(ast));
let variants_required = match reprs.as_slice() {
[EnumRepr::U8] | [EnumRepr::I8] => 1usize << 8,
[EnumRepr::U16] | [EnumRepr::I16] => 1usize << 16,
// `validate_reprs` has already validated that it's one of the preceding
// patterns.
_ => unreachable!(),
};
if enm.variants.len() != variants_required {
return Error::new_spanned(
ast,
format!(
"FromBytes only supported on {} enum with {} variants",
reprs[0], variants_required
),
)
.to_compile_error();
}
impl_block(ast, enm, Trait::FromBytes, RequireBoundedFields::Yes, false, None, None)
}
#[rustfmt::skip]
const ENUM_FROM_BYTES_CFG: Config<EnumRepr> = {
use EnumRepr::*;
Config {
allowed_combinations_message: r#"FromBytes requires repr of "u8", "u16", "i8", or "i16""#,
derive_unaligned: false,
allowed_combinations: &[
&[U8],
&[U16],
&[I8],
&[I16],
],
disallowed_but_legal_combinations: &[
&[C],
&[U32],
&[I32],
&[U64],
&[I64],
&[Usize],
&[Isize],
],
}
};
// Like structs, unions are `FromBytes` if
// - all fields are `FromBytes`
fn derive_from_bytes_union(ast: &DeriveInput, unn: &DataUnion) -> proc_macro2::TokenStream {
impl_block(ast, unn, Trait::FromBytes, RequireBoundedFields::Yes, false, None, None)
}
// A struct is `AsBytes` if:
// - all fields are `AsBytes`
// - `repr(C)` or `repr(transparent)` and
// - no padding (size of struct equals sum of size of field types)
// - `repr(packed)`
fn derive_as_bytes_struct(ast: &DeriveInput, strct: &DataStruct) -> proc_macro2::TokenStream {
let reprs = try_or_print!(STRUCT_UNION_AS_BYTES_CFG.validate_reprs(ast));
let is_transparent = reprs.contains(&StructRepr::Transparent);
let is_packed = reprs.contains(&StructRepr::Packed);
// TODO(#10): Support type parameters for non-transparent, non-packed
// structs.
if !ast.generics.params.is_empty() && !is_transparent && !is_packed {
return Error::new(
Span::call_site(),
"unsupported on generic structs that are not repr(transparent) or repr(packed)",
)
.to_compile_error();
}
// We don't need a padding check if the struct is repr(transparent) or
// repr(packed).
// - repr(transparent): The layout and ABI of the whole struct is the same
// as its only non-ZST field (meaning there's no padding outside of that
// field) and we require that field to be `AsBytes` (meaning there's no
// padding in that field).
// - repr(packed): Any inter-field padding bytes are removed, meaning that
// any padding bytes would need to come from the fields, all of which
// we require to be `AsBytes` (meaning they don't have any padding).
let padding_check = if is_transparent || is_packed { None } else { Some(PaddingCheck::Struct) };
impl_block(ast, strct, Trait::AsBytes, RequireBoundedFields::Yes, false, padding_check, None)
}
const STRUCT_UNION_AS_BYTES_CFG: Config<StructRepr> = Config {
// Since `disallowed_but_legal_combinations` is empty, this message will
// never actually be emitted.
allowed_combinations_message: r#"AsBytes requires either a) repr "C" or "transparent" with all fields implementing AsBytes or, b) repr "packed""#,
derive_unaligned: false,
allowed_combinations: STRUCT_UNION_ALLOWED_REPR_COMBINATIONS,
disallowed_but_legal_combinations: &[],
};
// An enum is `AsBytes` if it is C-like and has a defined repr.
fn derive_as_bytes_enum(ast: &DeriveInput, enm: &DataEnum) -> proc_macro2::TokenStream {
if !enm.is_c_like() {
return Error::new_spanned(ast, "only C-like enums can implement AsBytes")
.to_compile_error();
}
// We don't care what the repr is; we only care that it is one of the
// allowed ones.
let _: Vec<repr::EnumRepr> = try_or_print!(ENUM_AS_BYTES_CFG.validate_reprs(ast));
impl_block(ast, enm, Trait::AsBytes, RequireBoundedFields::No, false, None, None)
}
#[rustfmt::skip]
const ENUM_AS_BYTES_CFG: Config<EnumRepr> = {
use EnumRepr::*;
Config {
// Since `disallowed_but_legal_combinations` is empty, this message will
// never actually be emitted.
allowed_combinations_message: r#"AsBytes requires repr of "C", "u8", "u16", "u32", "u64", "usize", "i8", "i16", "i32", "i64", or "isize""#,
derive_unaligned: false,
allowed_combinations: &[
&[C],
&[U8],
&[U16],
&[I8],
&[I16],
&[U32],
&[I32],
&[U64],
&[I64],
&[Usize],
&[Isize],
],
disallowed_but_legal_combinations: &[],
}
};
// A union is `AsBytes` if:
// - all fields are `AsBytes`
// - `repr(C)`, `repr(transparent)`, or `repr(packed)`
// - no padding (size of union equals size of each field type)
fn derive_as_bytes_union(ast: &DeriveInput, unn: &DataUnion) -> proc_macro2::TokenStream {
// TODO(#10): Support type parameters.
if !ast.generics.params.is_empty() {
return Error::new(Span::call_site(), "unsupported on types with type parameters")
.to_compile_error();
}
try_or_print!(STRUCT_UNION_AS_BYTES_CFG.validate_reprs(ast));
impl_block(
ast,
unn,
Trait::AsBytes,
RequireBoundedFields::Yes,
false,
Some(PaddingCheck::Union),
None,
)
}
// A struct is `Unaligned` if:
// - `repr(align)` is no more than 1 and either
// - `repr(C)` or `repr(transparent)` and
// - all fields `Unaligned`
// - `repr(packed)`
fn derive_unaligned_struct(ast: &DeriveInput, strct: &DataStruct) -> proc_macro2::TokenStream {
let reprs = try_or_print!(STRUCT_UNION_UNALIGNED_CFG.validate_reprs(ast));
let require_trait_bounds_on_field_types = (!reprs.contains(&StructRepr::Packed)).into();
impl_block(ast, strct, Trait::Unaligned, require_trait_bounds_on_field_types, false, None, None)
}
const STRUCT_UNION_UNALIGNED_CFG: Config<StructRepr> = Config {
// Since `disallowed_but_legal_combinations` is empty, this message will
// never actually be emitted.
allowed_combinations_message: r#"Unaligned requires either a) repr "C" or "transparent" with all fields implementing Unaligned or, b) repr "packed""#,
derive_unaligned: true,
allowed_combinations: STRUCT_UNION_ALLOWED_REPR_COMBINATIONS,
disallowed_but_legal_combinations: &[],
};
// An enum is `Unaligned` if:
// - No `repr(align(N > 1))`
// - `repr(u8)` or `repr(i8)`
fn derive_unaligned_enum(ast: &DeriveInput, enm: &DataEnum) -> proc_macro2::TokenStream {
if !enm.is_c_like() {
return Error::new_spanned(ast, "only C-like enums can implement Unaligned")
.to_compile_error();
}
// The only valid reprs are `u8` and `i8`, and optionally `align(1)`. We
// don't actually care what the reprs are so long as they satisfy that
// requirement.
let _: Vec<repr::EnumRepr> = try_or_print!(ENUM_UNALIGNED_CFG.validate_reprs(ast));
// C-like enums cannot currently have type parameters, so this value of true
// for `require_trait_bound_on_field_types` doesn't really do anything. But
// it's marginally more future-proof in case that restriction is lifted in
// the future.
impl_block(ast, enm, Trait::Unaligned, RequireBoundedFields::Yes, false, None, None)
}
#[rustfmt::skip]
const ENUM_UNALIGNED_CFG: Config<EnumRepr> = {
use EnumRepr::*;
Config {
allowed_combinations_message:
r#"Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1)))"#,
derive_unaligned: true,
allowed_combinations: &[
&[U8],
&[I8],
],
disallowed_but_legal_combinations: &[
&[C],
&[U16],
&[U32],
&[U64],
&[Usize],
&[I16],
&[I32],
&[I64],
&[Isize],
],
}
};
// Like structs, a union is `Unaligned` if:
// - `repr(align)` is no more than 1 and either
// - `repr(C)` or `repr(transparent)` and
// - all fields `Unaligned`
// - `repr(packed)`
fn derive_unaligned_union(ast: &DeriveInput, unn: &DataUnion) -> proc_macro2::TokenStream {
let reprs = try_or_print!(STRUCT_UNION_UNALIGNED_CFG.validate_reprs(ast));
let require_trait_bound_on_field_types = (!reprs.contains(&StructRepr::Packed)).into();
impl_block(ast, unn, Trait::Unaligned, require_trait_bound_on_field_types, false, None, None)
}
// This enum describes what kind of padding check needs to be generated for the
// associated impl.
enum PaddingCheck {
// Check that the sum of the fields' sizes exactly equals the struct's size.
Struct,
// Check that the size of each field exactly equals the union's size.
Union,
}
impl PaddingCheck {
/// Returns the ident of the macro to call in order to validate that a type
/// passes the padding check encoded by `PaddingCheck`.
fn validator_macro_ident(&self) -> Ident {
let s = match self {
PaddingCheck::Struct => "struct_has_padding",
PaddingCheck::Union => "union_has_padding",
};
Ident::new(s, Span::call_site())
}
}
#[derive(Debug, Eq, PartialEq)]
enum Trait {
KnownLayout,
FromZeroes,
FromBytes,
AsBytes,
Unaligned,
}
impl Trait {
fn ident(&self) -> Ident {
Ident::new(format!("{:?}", self).as_str(), Span::call_site())
}
}
#[derive(Debug, Eq, PartialEq)]
enum RequireBoundedFields {
No,
Yes,
Trailing,
}
impl From<bool> for RequireBoundedFields {
fn from(do_require: bool) -> Self {
match do_require {
true => Self::Yes,
false => Self::No,
}
}
}
fn impl_block<D: DataExt>(
input: &DeriveInput,
data: &D,
trt: Trait,
require_trait_bound_on_field_types: RequireBoundedFields,
require_self_sized: bool,
padding_check: Option<PaddingCheck>,
extras: Option<proc_macro2::TokenStream>,
) -> proc_macro2::TokenStream {
// In this documentation, we will refer to this hypothetical struct:
//
// #[derive(FromBytes)]
// struct Foo<T, I: Iterator>
// where
// T: Copy,
// I: Clone,
// I::Item: Clone,
// {
// a: u8,
// b: T,
// c: I::Item,
// }
//
// We extract the field types, which in this case are `u8`, `T`, and
// `I::Item`. We re-use the existing parameters and where clauses. If
// `require_trait_bound == true` (as it is for `FromBytes), we add where
// bounds for each field's type:
//
// impl<T, I: Iterator> FromBytes for Foo<T, I>
// where
// T: Copy,
// I: Clone,
// I::Item: Clone,
// T: FromBytes,
// I::Item: FromBytes,
// {
// }
//
// NOTE: It is standard practice to only emit bounds for the type parameters
// themselves, not for field types based on those parameters (e.g., `T` vs
// `T::Foo`). For a discussion of why this is standard practice, see
// https://github.com/rust-lang/rust/issues/26925.
//
// The reason we diverge from this standard is that doing it that way for us
// would be unsound. E.g., consider a type, `T` where `T: FromBytes` but
// `T::Foo: !FromBytes`. It would not be sound for us to accept a type with
// a `T::Foo` field as `FromBytes` simply because `T: FromBytes`.
//
// While there's no getting around this requirement for us, it does have the
// pretty serious downside that, when lifetimes are involved, the trait
// solver ties itself in knots:
//
// #[derive(Unaligned)]
// #[repr(C)]
// struct Dup<'a, 'b> {
// a: PhantomData<&'a u8>,
// b: PhantomData<&'b u8>,
// }
//
// error[E0283]: type annotations required: cannot resolve `core::marker::PhantomData<&'a u8>: zerocopy::Unaligned`
// --> src/main.rs:6:10
// |
// 6 | #[derive(Unaligned)]
// | ^^^^^^^^^
// |
// = note: required by `zerocopy::Unaligned`
let type_ident = &input.ident;
let trait_ident = trt.ident();
let field_types = data.field_types();
let bound_tt = |ty| parse_quote!(#ty: ::zerocopy::#trait_ident);
let field_type_bounds: Vec<_> = match (require_trait_bound_on_field_types, &field_types[..]) {
(RequireBoundedFields::Yes, _) => field_types.iter().map(bound_tt).collect(),
(RequireBoundedFields::No, _) | (RequireBoundedFields::Trailing, []) => vec![],
(RequireBoundedFields::Trailing, [.., last]) => vec![bound_tt(last)],
};
// Don't bother emitting a padding check if there are no fields.
#[allow(unstable_name_collisions)] // See `BoolExt` below
let padding_check_bound = padding_check.and_then(|check| (!field_types.is_empty()).then_some(check)).map(|check| {
let fields = field_types.iter();
let validator_macro = check.validator_macro_ident();
parse_quote!(
::zerocopy::macro_util::HasPadding<#type_ident, {::zerocopy::#validator_macro!(#type_ident, #(#fields),*)}>:
::zerocopy::macro_util::ShouldBe<false>
)
});
let self_sized_bound = if require_self_sized { Some(parse_quote!(Self: Sized)) } else { None };
let bounds = input
.generics
.where_clause
.as_ref()
.map(|where_clause| where_clause.predicates.iter())
.into_iter()
.flatten()
.chain(field_type_bounds.iter())
.chain(padding_check_bound.iter())
.chain(self_sized_bound.iter());
// The parameters with trait bounds, but without type defaults.
let params = input.generics.params.clone().into_iter().map(|mut param| {
match &mut param {
GenericParam::Type(ty) => ty.default = None,
GenericParam::Const(cnst) => cnst.default = None,
GenericParam::Lifetime(_) => {}
}
quote!(#param)
});
// The identifiers of the parameters without trait bounds or type defaults.
let param_idents = input.generics.params.iter().map(|param| match param {
GenericParam::Type(ty) => {
let ident = &ty.ident;
quote!(#ident)
}
GenericParam::Lifetime(l) => {
let ident = &l.lifetime;
quote!(#ident)
}
GenericParam::Const(cnst) => {
let ident = &cnst.ident;
quote!({#ident})
}
});
quote! {
// TODO(#553): Add a test that generates a warning when
// `#[allow(deprecated)]` isn't present.
#[allow(deprecated)]
unsafe impl < #(#params),* > ::zerocopy::#trait_ident for #type_ident < #(#param_idents),* >
where
#(#bounds,)*
{
fn only_derive_is_allowed_to_implement_this_trait() {}
#extras
}
}
}
fn print_all_errors(errors: Vec<Error>) -> proc_macro2::TokenStream {
errors.iter().map(Error::to_compile_error).collect()
}
// A polyfill for `Option::then_some`, which was added after our MSRV.
//
// TODO(#67): Remove this once our MSRV is >= 1.62.
trait BoolExt {
fn then_some<T>(self, t: T) -> Option<T>;
}
impl BoolExt for bool {
fn then_some<T>(self, t: T) -> Option<T> {
if self {
Some(t)
} else {
None
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_config_repr_orderings() {
// Validate that the repr lists in the various configs are in the
// canonical order. If they aren't, then our algorithm to look up in
// those lists won't work.
// TODO(https://github.com/rust-lang/rust/issues/53485): Remove once
// `Vec::is_sorted` is stabilized.
fn is_sorted_and_deduped<T: Clone + Ord>(ts: &[T]) -> bool {
let mut sorted = ts.to_vec();
sorted.sort();
sorted.dedup();
ts == sorted.as_slice()
}
fn elements_are_sorted_and_deduped<T: Clone + Ord>(lists: &[&[T]]) -> bool {
lists.iter().all(|list| is_sorted_and_deduped(list))
}
fn config_is_sorted<T: KindRepr + Clone>(config: &Config<T>) -> bool {
elements_are_sorted_and_deduped(config.allowed_combinations)
&& elements_are_sorted_and_deduped(config.disallowed_but_legal_combinations)
}
assert!(config_is_sorted(&STRUCT_UNION_UNALIGNED_CFG));
assert!(config_is_sorted(&ENUM_FROM_BYTES_CFG));
assert!(config_is_sorted(&ENUM_UNALIGNED_CFG));
}
#[test]
fn test_config_repr_no_overlap() {
// Validate that no set of reprs appears in both the
// `allowed_combinations` and `disallowed_but_legal_combinations` lists.
fn overlap<T: Eq>(a: &[T], b: &[T]) -> bool {
a.iter().any(|elem| b.contains(elem))
}
fn config_overlaps<T: KindRepr + Eq>(config: &Config<T>) -> bool {
overlap(config.allowed_combinations, config.disallowed_but_legal_combinations)
}
assert!(!config_overlaps(&STRUCT_UNION_UNALIGNED_CFG));
assert!(!config_overlaps(&ENUM_FROM_BYTES_CFG));
assert!(!config_overlaps(&ENUM_UNALIGNED_CFG));
}
}

View file

@ -0,0 +1,311 @@
// 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.
use core::fmt::{self, Display, Formatter};
use {
proc_macro2::Span,
syn::punctuated::Punctuated,
syn::spanned::Spanned,
syn::token::Comma,
syn::{Attribute, DeriveInput, Error, LitInt, Meta},
};
pub struct Config<Repr: KindRepr> {
// A human-readable message describing what combinations of representations
// are allowed. This will be printed to the user if they use an invalid
// combination.
pub allowed_combinations_message: &'static str,
// Whether we're checking as part of `derive(Unaligned)`. If not, we can
// ignore `repr(align)`, which makes the code (and the list of valid repr
// combinations we have to enumerate) somewhat simpler. If we're checking
// for `Unaligned`, then in addition to checking against illegal
// combinations, we also check to see if there exists a `repr(align(N > 1))`
// attribute.
pub derive_unaligned: bool,
// Combinations which are valid for the trait.
pub allowed_combinations: &'static [&'static [Repr]],
// Combinations which are not valid for the trait, but are legal according
// to Rust. Any combination not in this or `allowed_combinations` is either
// illegal according to Rust or the behavior is unspecified. If the behavior
// is unspecified, it might become specified in the future, and that
// specification might not play nicely with our requirements. Thus, we
// reject combinations with unspecified behavior in addition to illegal
// combinations.
pub disallowed_but_legal_combinations: &'static [&'static [Repr]],
}
impl<R: KindRepr> Config<R> {
/// Validate that `input`'s representation attributes conform to the
/// requirements specified by this `Config`.
///
/// `validate_reprs` extracts the `repr` attributes, validates that they
/// conform to the requirements of `self`, and returns them. Regardless of
/// whether `align` attributes are considered during validation, they are
/// stripped out of the returned value since no callers care about them.
pub fn validate_reprs(&self, input: &DeriveInput) -> Result<Vec<R>, Vec<Error>> {
let mut metas_reprs = reprs(&input.attrs)?;
metas_reprs.sort_by(|a: &(_, R), b| a.1.partial_cmp(&b.1).unwrap());
if self.derive_unaligned {
if let Some((meta, _)) =
metas_reprs.iter().find(|&repr: &&(_, R)| repr.1.is_align_gt_one())
{
return Err(vec![Error::new_spanned(
meta,
"cannot derive Unaligned with repr(align(N > 1))",
)]);
}
}
let mut metas = Vec::new();
let mut reprs = Vec::new();
metas_reprs.into_iter().filter(|(_, repr)| !repr.is_align()).for_each(|(meta, repr)| {
metas.push(meta);
reprs.push(repr)
});
if reprs.is_empty() {
// Use `Span::call_site` to report this error on the
// `#[derive(...)]` itself.
return Err(vec![Error::new(Span::call_site(), "must have a non-align #[repr(...)] attribute in order to guarantee this type's memory layout")]);
}
let initial_sp = metas[0].span();
let err_span = metas.iter().skip(1).try_fold(initial_sp, |sp, meta| sp.join(meta.span()));
if self.allowed_combinations.contains(&reprs.as_slice()) {
Ok(reprs)
} else if self.disallowed_but_legal_combinations.contains(&reprs.as_slice()) {
Err(vec![Error::new(
err_span.unwrap_or_else(|| input.span()),
self.allowed_combinations_message,
)])
} else {
Err(vec![Error::new(
err_span.unwrap_or_else(|| input.span()),
"conflicting representation hints",
)])
}
}
}
// The type of valid reprs for a particular kind (enum, struct, union).
pub trait KindRepr: 'static + Sized + Ord {
fn is_align(&self) -> bool;
fn is_align_gt_one(&self) -> bool;
fn parse(meta: &Meta) -> syn::Result<Self>;
}
// Defines an enum for reprs which are valid for a given kind (structs, enums,
// etc), and provide implementations of `KindRepr`, `Ord`, and `Display`, and
// those traits' super-traits.
macro_rules! define_kind_specific_repr {
($type_name:expr, $repr_name:ident, [ $($repr_variant:ident),* ] , [ $($repr_variant_aligned:ident),* ]) => {
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum $repr_name {
$($repr_variant,)*
$($repr_variant_aligned(u64),)*
}
impl KindRepr for $repr_name {
fn is_align(&self) -> bool {
match self {
$($repr_name::$repr_variant_aligned(_) => true,)*
_ => false,
}
}
fn is_align_gt_one(&self) -> bool {
match self {
// `packed(n)` only lowers alignment
$repr_name::Align(n) => n > &1,
_ => false,
}
}
fn parse(meta: &Meta) -> syn::Result<$repr_name> {
match Repr::from_meta(meta)? {
$(Repr::$repr_variant => Ok($repr_name::$repr_variant),)*
$(Repr::$repr_variant_aligned(u) => Ok($repr_name::$repr_variant_aligned(u)),)*
_ => Err(Error::new_spanned(meta, concat!("unsupported representation for deriving FromBytes, AsBytes, or Unaligned on ", $type_name)))
}
}
}
// Define a stable ordering so we can canonicalize lists of reprs. The
// ordering itself doesn't matter so long as it's stable.
impl PartialOrd for $repr_name {
fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
Some(self.cmp(other))
}
}
impl Ord for $repr_name {
fn cmp(&self, other: &Self) -> core::cmp::Ordering {
format!("{:?}", self).cmp(&format!("{:?}", other))
}
}
impl core::fmt::Display for $repr_name {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
$($repr_name::$repr_variant => Repr::$repr_variant,)*
$($repr_name::$repr_variant_aligned(u) => Repr::$repr_variant_aligned(*u),)*
}.fmt(f)
}
}
}
}
define_kind_specific_repr!("a struct", StructRepr, [C, Transparent, Packed], [Align, PackedN]);
define_kind_specific_repr!(
"an enum",
EnumRepr,
[C, U8, U16, U32, U64, Usize, I8, I16, I32, I64, Isize],
[Align]
);
// All representations known to Rust.
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
pub enum Repr {
U8,
U16,
U32,
U64,
Usize,
I8,
I16,
I32,
I64,
Isize,
C,
Transparent,
Packed,
PackedN(u64),
Align(u64),
}
impl Repr {
fn from_meta(meta: &Meta) -> Result<Repr, Error> {
let (path, list) = match meta {
Meta::Path(path) => (path, None),
Meta::List(list) => (&list.path, Some(list)),
_ => return Err(Error::new_spanned(meta, "unrecognized representation hint")),
};
let ident = path
.get_ident()
.ok_or_else(|| Error::new_spanned(meta, "unrecognized representation hint"))?;
Ok(match (ident.to_string().as_str(), list) {
("u8", None) => Repr::U8,
("u16", None) => Repr::U16,
("u32", None) => Repr::U32,
("u64", None) => Repr::U64,
("usize", None) => Repr::Usize,
("i8", None) => Repr::I8,
("i16", None) => Repr::I16,
("i32", None) => Repr::I32,
("i64", None) => Repr::I64,
("isize", None) => Repr::Isize,
("C", None) => Repr::C,
("transparent", None) => Repr::Transparent,
("packed", None) => Repr::Packed,
("packed", Some(list)) => {
Repr::PackedN(list.parse_args::<LitInt>()?.base10_parse::<u64>()?)
}
("align", Some(list)) => {
Repr::Align(list.parse_args::<LitInt>()?.base10_parse::<u64>()?)
}
_ => return Err(Error::new_spanned(meta, "unrecognized representation hint")),
})
}
}
impl KindRepr for Repr {
fn is_align(&self) -> bool {
false
}
fn is_align_gt_one(&self) -> bool {
false
}
fn parse(meta: &Meta) -> syn::Result<Self> {
Self::from_meta(meta)
}
}
impl Display for Repr {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> {
if let Repr::Align(n) = self {
return write!(f, "repr(align({}))", n);
}
if let Repr::PackedN(n) = self {
return write!(f, "repr(packed({}))", n);
}
write!(
f,
"repr({})",
match self {
Repr::U8 => "u8",
Repr::U16 => "u16",
Repr::U32 => "u32",
Repr::U64 => "u64",
Repr::Usize => "usize",
Repr::I8 => "i8",
Repr::I16 => "i16",
Repr::I32 => "i32",
Repr::I64 => "i64",
Repr::Isize => "isize",
Repr::C => "C",
Repr::Transparent => "transparent",
Repr::Packed => "packed",
_ => unreachable!(),
}
)
}
}
pub(crate) fn reprs<R: KindRepr>(attrs: &[Attribute]) -> Result<Vec<(Meta, R)>, Vec<Error>> {
let mut reprs = Vec::new();
let mut errors = Vec::new();
for attr in attrs {
// Ignore documentation attributes.
if attr.path().is_ident("doc") {
continue;
}
if let Meta::List(ref meta_list) = attr.meta {
if meta_list.path.is_ident("repr") {
let parsed: Punctuated<Meta, Comma> =
match meta_list.parse_args_with(Punctuated::parse_terminated) {
Ok(parsed) => parsed,
Err(_) => {
errors.push(Error::new_spanned(
&meta_list.tokens,
"unrecognized representation hint",
));
continue;
}
};
for meta in parsed {
match R::parse(&meta) {
Ok(repr) => reprs.push((meta, repr)),
Err(err) => errors.push(err),
}
}
}
}
}
if !errors.is_empty() {
return Err(errors);
}
Ok(reprs)
}

View file

@ -0,0 +1,101 @@
// 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.
#![allow(warnings)]
use {static_assertions::assert_impl_all, zerocopy::AsBytes};
// An enum is `AsBytes` if if has a defined repr.
#[derive(AsBytes)]
#[repr(C)]
enum C {
A,
}
assert_impl_all!(C: AsBytes);
#[derive(AsBytes)]
#[repr(u8)]
enum U8 {
A,
}
assert_impl_all!(U8: AsBytes);
#[derive(AsBytes)]
#[repr(u16)]
enum U16 {
A,
}
assert_impl_all!(U16: AsBytes);
#[derive(AsBytes)]
#[repr(u32)]
enum U32 {
A,
}
assert_impl_all!(U32: AsBytes);
#[derive(AsBytes)]
#[repr(u64)]
enum U64 {
A,
}
assert_impl_all!(U64: AsBytes);
#[derive(AsBytes)]
#[repr(usize)]
enum Usize {
A,
}
assert_impl_all!(Usize: AsBytes);
#[derive(AsBytes)]
#[repr(i8)]
enum I8 {
A,
}
assert_impl_all!(I8: AsBytes);
#[derive(AsBytes)]
#[repr(i16)]
enum I16 {
A,
}
assert_impl_all!(I16: AsBytes);
#[derive(AsBytes)]
#[repr(i32)]
enum I32 {
A,
}
assert_impl_all!(I32: AsBytes);
#[derive(AsBytes)]
#[repr(i64)]
enum I64 {
A,
}
assert_impl_all!(I64: AsBytes);
#[derive(AsBytes)]
#[repr(isize)]
enum Isize {
A,
}
assert_impl_all!(Isize: AsBytes);

View file

@ -0,0 +1,35 @@
// 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.
#![allow(warnings)]
mod util;
use {static_assertions::assert_impl_all, zerocopy::FromZeroes};
#[derive(FromZeroes)]
enum Foo {
A,
}
assert_impl_all!(Foo: FromZeroes);
#[derive(FromZeroes)]
enum Bar {
A = 0,
}
assert_impl_all!(Bar: FromZeroes);
#[derive(FromZeroes)]
enum Baz {
A = 1,
B = 0,
}
assert_impl_all!(Baz: FromZeroes);

View file

@ -0,0 +1,46 @@
// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#![allow(warnings)]
mod util;
use {core::marker::PhantomData, static_assertions::assert_impl_all, zerocopy::KnownLayout};
#[derive(KnownLayout)]
enum Foo {
A,
}
assert_impl_all!(Foo: KnownLayout);
#[derive(KnownLayout)]
enum Bar {
A = 0,
}
assert_impl_all!(Bar: KnownLayout);
#[derive(KnownLayout)]
enum Baz {
A = 1,
B = 0,
}
assert_impl_all!(Baz: KnownLayout);
// Deriving `KnownLayout` should work if the enum has bounded parameters.
#[derive(KnownLayout)]
#[repr(C)]
enum WithParams<'a: 'b, 'b: 'a, const N: usize, T: 'a + 'b + KnownLayout>
where
'a: 'b,
'b: 'a,
T: 'a + 'b + KnownLayout,
{
Variant([T; N], PhantomData<&'a &'b ()>),
}
assert_impl_all!(WithParams<'static, 'static, 42, u8>: KnownLayout);

View file

@ -0,0 +1,47 @@
// 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.
#![allow(warnings)]
use {static_assertions::assert_impl_all, zerocopy::Unaligned};
// An enum is `Unaligned` if:
// - No `repr(align(N > 1))`
// - `repr(u8)` or `repr(i8)`
#[derive(Unaligned)]
#[repr(u8)]
enum Foo {
A,
}
assert_impl_all!(Foo: Unaligned);
#[derive(Unaligned)]
#[repr(i8)]
enum Bar {
A,
}
assert_impl_all!(Bar: Unaligned);
#[derive(Unaligned)]
#[repr(u8, align(1))]
enum Baz {
A,
}
assert_impl_all!(Baz: Unaligned);
#[derive(Unaligned)]
#[repr(i8, align(1))]
enum Blah {
B,
}
assert_impl_all!(Blah: Unaligned);

View file

@ -0,0 +1,43 @@
// 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.
// Make sure that macro hygiene will ensure that when we reference "zerocopy",
// that will work properly even if they've renamed the crate and have not
// imported its traits.
#![allow(warnings)]
extern crate zerocopy as _zerocopy;
#[macro_use]
mod util;
use std::{marker::PhantomData, option::IntoIter};
use static_assertions::assert_impl_all;
#[derive(
_zerocopy::KnownLayout, _zerocopy::FromZeroes, _zerocopy::FromBytes, _zerocopy::Unaligned,
)]
#[repr(C)]
struct TypeParams<'a, T, I: Iterator> {
a: T,
c: I::Item,
d: u8,
e: PhantomData<&'a [u8]>,
f: PhantomData<&'static str>,
g: PhantomData<String>,
}
assert_impl_all!(
TypeParams<'static, (), IntoIter<()>>:
_zerocopy::KnownLayout,
_zerocopy::FromZeroes,
_zerocopy::FromBytes,
_zerocopy::Unaligned
);

View file

@ -0,0 +1,38 @@
// 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.
#![allow(warnings)]
use zerocopy::{AsBytes, FromBytes, FromZeroes, Unaligned};
// Ensure that types that are use'd and types that are referenced by path work.
mod foo {
use zerocopy::{AsBytes, FromBytes, FromZeroes, Unaligned};
#[derive(FromZeroes, FromBytes, AsBytes, Unaligned)]
#[repr(C)]
pub struct Foo {
foo: u8,
}
#[derive(FromZeroes, FromBytes, AsBytes, Unaligned)]
#[repr(C)]
pub struct Bar {
bar: u8,
}
}
use foo::Foo;
#[derive(FromZeroes, FromBytes, AsBytes, Unaligned)]
#[repr(C)]
struct Baz {
foo: Foo,
bar: foo::Bar,
}

View file

@ -0,0 +1,24 @@
// 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.
use zerocopy::{AsBytes, FromBytes, FromZeroes, KnownLayout, Unaligned};
// These derives do not result in E0446 as of Rust 1.59.0, because of
// https://github.com/rust-lang/rust/pull/90586.
//
// This change eliminates one of the major downsides of emitting `where`
// bounds for field types (i.e., the emission of E0446 for private field
// types).
#[derive(KnownLayout, AsBytes, FromZeroes, FromBytes, Unaligned)]
#[repr(C)]
pub struct Public(Private);
#[derive(KnownLayout, AsBytes, FromZeroes, FromBytes, Unaligned)]
#[repr(C)]
struct Private(());

View file

@ -0,0 +1,161 @@
// 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.
#![allow(warnings)]
mod util;
use std::{marker::PhantomData, mem::ManuallyDrop, option::IntoIter};
use {static_assertions::assert_impl_all, zerocopy::AsBytes};
use self::util::AU16;
// A struct is `AsBytes` if:
// - all fields are `AsBytes`
// - `repr(C)` or `repr(transparent)` and
// - no padding (size of struct equals sum of size of field types)
// - `repr(packed)`
#[derive(AsBytes)]
#[repr(C)]
struct CZst;
assert_impl_all!(CZst: AsBytes);
#[derive(AsBytes)]
#[repr(C)]
struct C {
a: u8,
b: u8,
c: AU16,
}
assert_impl_all!(C: AsBytes);
#[derive(AsBytes)]
#[repr(transparent)]
struct Transparent {
a: u8,
b: CZst,
}
assert_impl_all!(Transparent: AsBytes);
#[derive(AsBytes)]
#[repr(transparent)]
struct TransparentGeneric<T: ?Sized> {
a: CZst,
b: T,
}
assert_impl_all!(TransparentGeneric<u64>: AsBytes);
assert_impl_all!(TransparentGeneric<[u64]>: AsBytes);
#[derive(AsBytes)]
#[repr(C, packed)]
struct CZstPacked;
assert_impl_all!(CZstPacked: AsBytes);
#[derive(AsBytes)]
#[repr(C, packed)]
struct CPacked {
a: u8,
// NOTE: The `u16` type is not guaranteed to have alignment 2, although it
// does on many platforms. However, to fix this would require a custom type
// with a `#[repr(align(2))]` attribute, and `#[repr(packed)]` types are not
// allowed to transitively contain `#[repr(align(...))]` types. Thus, we
// have no choice but to use `u16` here. Luckily, these tests run in CI on
// platforms on which `u16` has alignment 2, so this isn't that big of a
// deal.
b: u16,
}
assert_impl_all!(CPacked: AsBytes);
#[derive(AsBytes)]
#[repr(C, packed(2))]
// The same caveats as for CPacked apply - we're assuming u64 is at least
// 4-byte aligned by default. Without packed(2), this should fail, as there
// would be padding between a/b assuming u64 is 4+ byte aligned.
struct CPacked2 {
a: u16,
b: u64,
}
assert_impl_all!(CPacked2: AsBytes);
#[derive(AsBytes)]
#[repr(C, packed)]
struct CPackedGeneric<T, U: ?Sized> {
t: T,
// Unsized types stored in `repr(packed)` structs must not be dropped
// because dropping them in-place might be unsound depending on the
// alignment of the outer struct. Sized types can be dropped by first being
// moved to an aligned stack variable, but this isn't possible with unsized
// types.
u: ManuallyDrop<U>,
}
assert_impl_all!(CPackedGeneric<u8, AU16>: AsBytes);
assert_impl_all!(CPackedGeneric<u8, [AU16]>: AsBytes);
#[derive(AsBytes)]
#[repr(packed)]
struct Packed {
a: u8,
// NOTE: The `u16` type is not guaranteed to have alignment 2, although it
// does on many platforms. However, to fix this would require a custom type
// with a `#[repr(align(2))]` attribute, and `#[repr(packed)]` types are not
// allowed to transitively contain `#[repr(align(...))]` types. Thus, we
// have no choice but to use `u16` here. Luckily, these tests run in CI on
// platforms on which `u16` has alignment 2, so this isn't that big of a
// deal.
b: u16,
}
assert_impl_all!(Packed: AsBytes);
#[derive(AsBytes)]
#[repr(packed)]
struct PackedGeneric<T, U: ?Sized> {
t: T,
// Unsized types stored in `repr(packed)` structs must not be dropped
// because dropping them in-place might be unsound depending on the
// alignment of the outer struct. Sized types can be dropped by first being
// moved to an aligned stack variable, but this isn't possible with unsized
// types.
u: ManuallyDrop<U>,
}
assert_impl_all!(PackedGeneric<u8, AU16>: AsBytes);
assert_impl_all!(PackedGeneric<u8, [AU16]>: AsBytes);
#[derive(AsBytes)]
#[repr(transparent)]
struct Unsized {
a: [u8],
}
assert_impl_all!(Unsized: AsBytes);
// Deriving `AsBytes` should work if the struct has bounded parameters.
#[derive(AsBytes)]
#[repr(transparent)]
struct WithParams<'a: 'b, 'b: 'a, const N: usize, T: 'a + 'b + AsBytes>(
[T; N],
PhantomData<&'a &'b ()>,
)
where
'a: 'b,
'b: 'a,
T: 'a + 'b + AsBytes;
assert_impl_all!(WithParams<'static, 'static, 42, u8>: AsBytes);

View file

@ -0,0 +1,79 @@
// 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.
#![allow(warnings)]
mod util;
use std::{marker::PhantomData, option::IntoIter};
use {
static_assertions::assert_impl_all,
zerocopy::{FromBytes, FromZeroes},
};
use crate::util::AU16;
// A struct is `FromBytes` if:
// - all fields are `FromBytes`
#[derive(FromZeroes, FromBytes)]
struct Zst;
assert_impl_all!(Zst: FromBytes);
#[derive(FromZeroes, FromBytes)]
struct One {
a: u8,
}
assert_impl_all!(One: FromBytes);
#[derive(FromZeroes, FromBytes)]
struct Two {
a: u8,
b: Zst,
}
assert_impl_all!(Two: FromBytes);
#[derive(FromZeroes, FromBytes)]
struct Unsized {
a: [u8],
}
assert_impl_all!(Unsized: FromBytes);
#[derive(FromZeroes, FromBytes)]
struct TypeParams<'a, T: ?Sized, I: Iterator> {
a: I::Item,
b: u8,
c: PhantomData<&'a [u8]>,
d: PhantomData<&'static str>,
e: PhantomData<String>,
f: T,
}
assert_impl_all!(TypeParams<'static, (), IntoIter<()>>: FromBytes);
assert_impl_all!(TypeParams<'static, AU16, IntoIter<()>>: FromBytes);
assert_impl_all!(TypeParams<'static, [AU16], IntoIter<()>>: FromBytes);
// Deriving `FromBytes` should work if the struct has bounded parameters.
#[derive(FromZeroes, FromBytes)]
#[repr(transparent)]
struct WithParams<'a: 'b, 'b: 'a, const N: usize, T: 'a + 'b + FromBytes>(
[T; N],
PhantomData<&'a &'b ()>,
)
where
'a: 'b,
'b: 'a,
T: 'a + 'b + FromBytes;
assert_impl_all!(WithParams<'static, 'static, 42, u8>: FromBytes);

View file

@ -0,0 +1,77 @@
// 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.
#![allow(warnings)]
#[macro_use]
mod util;
use std::{marker::PhantomData, option::IntoIter};
use {static_assertions::assert_impl_all, zerocopy::FromZeroes};
use crate::util::AU16;
// A struct is `FromZeroes` if:
// - all fields are `FromZeroes`
#[derive(FromZeroes)]
struct Zst;
assert_impl_all!(Zst: FromZeroes);
#[derive(FromZeroes)]
struct One {
a: bool,
}
assert_impl_all!(One: FromZeroes);
#[derive(FromZeroes)]
struct Two {
a: bool,
b: Zst,
}
assert_impl_all!(Two: FromZeroes);
#[derive(FromZeroes)]
struct Unsized {
a: [u8],
}
assert_impl_all!(Unsized: FromZeroes);
#[derive(FromZeroes)]
struct TypeParams<'a, T: ?Sized, I: Iterator> {
a: I::Item,
b: u8,
c: PhantomData<&'a [u8]>,
d: PhantomData<&'static str>,
e: PhantomData<String>,
f: T,
}
assert_impl_all!(TypeParams<'static, (), IntoIter<()>>: FromZeroes);
assert_impl_all!(TypeParams<'static, AU16, IntoIter<()>>: FromZeroes);
assert_impl_all!(TypeParams<'static, [AU16], IntoIter<()>>: FromZeroes);
// Deriving `FromZeroes` should work if the struct has bounded parameters.
#[derive(FromZeroes)]
#[repr(transparent)]
struct WithParams<'a: 'b, 'b: 'a, const N: usize, T: 'a + 'b + FromZeroes>(
[T; N],
PhantomData<&'a &'b ()>,
)
where
'a: 'b,
'b: 'a,
T: 'a + 'b + FromZeroes;
assert_impl_all!(WithParams<'static, 'static, 42, u8>: FromZeroes);

View file

@ -0,0 +1,65 @@
// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#![allow(warnings)]
#[macro_use]
mod util;
use std::{marker::PhantomData, option::IntoIter};
use {
static_assertions::assert_impl_all,
zerocopy::{DstLayout, KnownLayout},
};
use crate::util::AU16;
#[derive(KnownLayout)]
struct Zst;
assert_impl_all!(Zst: KnownLayout);
#[derive(KnownLayout)]
struct One {
a: bool,
}
assert_impl_all!(One: KnownLayout);
#[derive(KnownLayout)]
struct Two {
a: bool,
b: Zst,
}
assert_impl_all!(Two: KnownLayout);
#[derive(KnownLayout)]
struct TypeParams<'a, T, I: Iterator> {
a: I::Item,
b: u8,
c: PhantomData<&'a [u8]>,
d: PhantomData<&'static str>,
e: PhantomData<String>,
f: T,
}
assert_impl_all!(TypeParams<'static, (), IntoIter<()>>: KnownLayout);
assert_impl_all!(TypeParams<'static, AU16, IntoIter<()>>: KnownLayout);
// Deriving `KnownLayout` should work if the struct has bounded parameters.
#[derive(KnownLayout)]
#[repr(C)]
struct WithParams<'a: 'b, 'b: 'a, const N: usize, T: 'a + 'b + KnownLayout>(
[T; N],
PhantomData<&'a &'b ()>,
)
where
'a: 'b,
'b: 'a,
T: 'a + 'b + KnownLayout;
assert_impl_all!(WithParams<'static, 'static, 42, u8>: KnownLayout);

View file

@ -0,0 +1,100 @@
// 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.
#![allow(warnings)]
mod util;
use std::{marker::PhantomData, option::IntoIter};
use {static_assertions::assert_impl_all, zerocopy::Unaligned};
use crate::util::AU16;
// A struct is `Unaligned` if:
// - `repr(align)` is no more than 1 and either
// - `repr(C)` or `repr(transparent)` and
// - all fields Unaligned
// - `repr(packed)`
#[derive(Unaligned)]
#[repr(C)]
struct Foo {
a: u8,
}
assert_impl_all!(Foo: Unaligned);
#[derive(Unaligned)]
#[repr(transparent)]
struct Bar {
a: u8,
}
assert_impl_all!(Bar: Unaligned);
#[derive(Unaligned)]
#[repr(packed)]
struct Baz {
// NOTE: The `u16` type is not guaranteed to have alignment 2, although it
// does on many platforms. However, to fix this would require a custom type
// with a `#[repr(align(2))]` attribute, and `#[repr(packed)]` types are not
// allowed to transitively contain `#[repr(align(...))]` types. Thus, we
// have no choice but to use `u16` here. Luckily, these tests run in CI on
// platforms on which `u16` has alignment 2, so this isn't that big of a
// deal.
a: u16,
}
assert_impl_all!(Baz: Unaligned);
#[derive(Unaligned)]
#[repr(C, align(1))]
struct FooAlign {
a: u8,
}
assert_impl_all!(FooAlign: Unaligned);
#[derive(Unaligned)]
#[repr(transparent)]
struct Unsized {
a: [u8],
}
assert_impl_all!(Unsized: Unaligned);
#[derive(Unaligned)]
#[repr(C)]
struct TypeParams<'a, T: ?Sized, I: Iterator> {
a: I::Item,
b: u8,
c: PhantomData<&'a [u8]>,
d: PhantomData<&'static str>,
e: PhantomData<String>,
f: T,
}
assert_impl_all!(TypeParams<'static, (), IntoIter<()>>: Unaligned);
assert_impl_all!(TypeParams<'static, u8, IntoIter<()>>: Unaligned);
assert_impl_all!(TypeParams<'static, [u8], IntoIter<()>>: Unaligned);
// Deriving `Unaligned` should work if the struct has bounded parameters.
#[derive(Unaligned)]
#[repr(transparent)]
struct WithParams<'a: 'b, 'b: 'a, const N: usize, T: 'a + 'b + Unaligned>(
[T; N],
PhantomData<&'a &'b ()>,
)
where
'a: 'b,
'b: 'a,
T: 'a + 'b + Unaligned;
assert_impl_all!(WithParams<'static, 'static, 42, u8>: Unaligned);

View file

@ -0,0 +1,19 @@
// 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.
#[test]
#[cfg_attr(miri, ignore)]
fn ui() {
let version = testutil::ToolchainVersion::extract_from_pwd().unwrap();
// See the doc comment on this method for an explanation of what this does
// and why we store source files in different directories.
let source_files_dirname = version.get_ui_source_files_dirname_and_maybe_print_warning();
let t = trybuild::TestCases::new();
t.compile_fail(format!("tests/{source_files_dirname}/*.rs"));
}

View file

@ -0,0 +1,40 @@
// 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.
extern crate zerocopy;
#[path = "../util.rs"]
mod util;
use core::marker::PhantomData;
use {
static_assertions::assert_impl_all,
zerocopy::{AsBytes, FromBytes, FromZeroes, Unaligned},
};
use self::util::NotZerocopy;
fn main() {}
// Test generic transparent structs
#[derive(AsBytes, FromZeroes, FromBytes, Unaligned)]
#[repr(transparent)]
struct TransparentStruct<T> {
inner: T,
_phantom: PhantomData<()>,
}
// It should be legal to derive these traits on a transparent struct, but it
// must also ensure the traits are only implemented when the inner type
// implements them.
assert_impl_all!(TransparentStruct<NotZerocopy>: FromZeroes);
assert_impl_all!(TransparentStruct<NotZerocopy>: FromBytes);
assert_impl_all!(TransparentStruct<NotZerocopy>: AsBytes);
assert_impl_all!(TransparentStruct<NotZerocopy>: Unaligned);

View file

@ -0,0 +1,71 @@
error[E0277]: the trait bound `NotZerocopy: FromZeroes` is not satisfied
--> tests/ui-msrv/derive_transparent.rs:37:1
|
37 | assert_impl_all!(TransparentStruct<NotZerocopy>: FromZeroes);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `FromZeroes` is not implemented for `NotZerocopy`
|
note: required because of the requirements on the impl of `FromZeroes` for `TransparentStruct<NotZerocopy>`
--> tests/ui-msrv/derive_transparent.rs:27:19
|
27 | #[derive(AsBytes, FromZeroes, FromBytes, Unaligned)]
| ^^^^^^^^^^
note: required by a bound in `_::{closure#0}::assert_impl_all`
--> tests/ui-msrv/derive_transparent.rs:37:1
|
37 | assert_impl_all!(TransparentStruct<NotZerocopy>: FromZeroes);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `_::{closure#0}::assert_impl_all`
= note: this error originates in the macro `assert_impl_all` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `NotZerocopy: FromBytes` is not satisfied
--> tests/ui-msrv/derive_transparent.rs:38:1
|
38 | assert_impl_all!(TransparentStruct<NotZerocopy>: FromBytes);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `FromBytes` is not implemented for `NotZerocopy`
|
note: required because of the requirements on the impl of `FromBytes` for `TransparentStruct<NotZerocopy>`
--> tests/ui-msrv/derive_transparent.rs:27:31
|
27 | #[derive(AsBytes, FromZeroes, FromBytes, Unaligned)]
| ^^^^^^^^^
note: required by a bound in `_::{closure#0}::assert_impl_all`
--> tests/ui-msrv/derive_transparent.rs:38:1
|
38 | assert_impl_all!(TransparentStruct<NotZerocopy>: FromBytes);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `_::{closure#0}::assert_impl_all`
= note: this error originates in the macro `assert_impl_all` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `NotZerocopy: AsBytes` is not satisfied
--> tests/ui-msrv/derive_transparent.rs:39:1
|
39 | assert_impl_all!(TransparentStruct<NotZerocopy>: AsBytes);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `AsBytes` is not implemented for `NotZerocopy`
|
note: required because of the requirements on the impl of `AsBytes` for `TransparentStruct<NotZerocopy>`
--> tests/ui-msrv/derive_transparent.rs:27:10
|
27 | #[derive(AsBytes, FromZeroes, FromBytes, Unaligned)]
| ^^^^^^^
note: required by a bound in `_::{closure#0}::assert_impl_all`
--> tests/ui-msrv/derive_transparent.rs:39:1
|
39 | assert_impl_all!(TransparentStruct<NotZerocopy>: AsBytes);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `_::{closure#0}::assert_impl_all`
= note: this error originates in the macro `assert_impl_all` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `NotZerocopy: Unaligned` is not satisfied
--> tests/ui-msrv/derive_transparent.rs:40:1
|
40 | assert_impl_all!(TransparentStruct<NotZerocopy>: Unaligned);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Unaligned` is not implemented for `NotZerocopy`
|
note: required because of the requirements on the impl of `Unaligned` for `TransparentStruct<NotZerocopy>`
--> tests/ui-msrv/derive_transparent.rs:27:42
|
27 | #[derive(AsBytes, FromZeroes, FromBytes, Unaligned)]
| ^^^^^^^^^
note: required by a bound in `_::{closure#0}::assert_impl_all`
--> tests/ui-msrv/derive_transparent.rs:40:1
|
40 | assert_impl_all!(TransparentStruct<NotZerocopy>: Unaligned);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `_::{closure#0}::assert_impl_all`
= note: this error originates in the macro `assert_impl_all` (in Nightly builds, run with -Z macro-backtrace for more info)

View file

@ -0,0 +1,194 @@
// 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.
#[macro_use]
extern crate zerocopy;
fn main() {}
//
// Generic errors
//
#[derive(FromZeroes, FromBytes)]
#[repr("foo")]
enum Generic1 {
A,
}
#[derive(FromZeroes, FromBytes)]
#[repr(foo)]
enum Generic2 {
A,
}
#[derive(FromZeroes, FromBytes)]
#[repr(transparent)]
enum Generic3 {
A,
}
#[derive(FromZeroes, FromBytes)]
#[repr(u8, u16)]
enum Generic4 {
A,
}
#[derive(FromZeroes, FromBytes)]
enum Generic5 {
A,
}
//
// FromZeroes errors
//
#[derive(FromZeroes)]
enum FromZeroes1 {
A(u8),
}
#[derive(FromZeroes)]
enum FromZeroes2 {
A,
B(u8),
}
#[derive(FromZeroes)]
enum FromZeroes3 {
A = 1,
B,
}
//
// FromBytes errors
//
#[derive(FromZeroes, FromBytes)]
#[repr(C)]
enum FromBytes1 {
A,
}
#[derive(FromZeroes, FromBytes)]
#[repr(usize)]
enum FromBytes2 {
A,
}
#[derive(FromZeroes, FromBytes)]
#[repr(isize)]
enum FromBytes3 {
A,
}
#[derive(FromZeroes, FromBytes)]
#[repr(u32)]
enum FromBytes4 {
A,
}
#[derive(FromZeroes, FromBytes)]
#[repr(i32)]
enum FromBytes5 {
A,
}
#[derive(FromZeroes, FromBytes)]
#[repr(u64)]
enum FromBytes6 {
A,
}
#[derive(FromZeroes, FromBytes)]
#[repr(i64)]
enum FromBytes7 {
A,
}
//
// Unaligned errors
//
#[derive(Unaligned)]
#[repr(C)]
enum Unaligned1 {
A,
}
#[derive(Unaligned)]
#[repr(u16)]
enum Unaligned2 {
A,
}
#[derive(Unaligned)]
#[repr(i16)]
enum Unaligned3 {
A,
}
#[derive(Unaligned)]
#[repr(u32)]
enum Unaligned4 {
A,
}
#[derive(Unaligned)]
#[repr(i32)]
enum Unaligned5 {
A,
}
#[derive(Unaligned)]
#[repr(u64)]
enum Unaligned6 {
A,
}
#[derive(Unaligned)]
#[repr(i64)]
enum Unaligned7 {
A,
}
#[derive(Unaligned)]
#[repr(usize)]
enum Unaligned8 {
A,
}
#[derive(Unaligned)]
#[repr(isize)]
enum Unaligned9 {
A,
}
#[derive(Unaligned)]
#[repr(u8, align(2))]
enum Unaligned10 {
A,
}
#[derive(Unaligned)]
#[repr(i8, align(2))]
enum Unaligned11 {
A,
}
#[derive(Unaligned)]
#[repr(align(1), align(2))]
enum Unaligned12 {
A,
}
#[derive(Unaligned)]
#[repr(align(2), align(4))]
enum Unaligned13 {
A,
}

View file

@ -0,0 +1,199 @@
error: unrecognized representation hint
--> tests/ui-msrv/enum.rs:19:8
|
19 | #[repr("foo")]
| ^^^^^
error: unrecognized representation hint
--> tests/ui-msrv/enum.rs:25:8
|
25 | #[repr(foo)]
| ^^^
error: unsupported representation for deriving FromBytes, AsBytes, or Unaligned on an enum
--> tests/ui-msrv/enum.rs:31:8
|
31 | #[repr(transparent)]
| ^^^^^^^^^^^
error: conflicting representation hints
--> tests/ui-msrv/enum.rs:37:1
|
37 | #[repr(u8, u16)]
| ^
error: must have a non-align #[repr(...)] attribute in order to guarantee this type's memory layout
--> tests/ui-msrv/enum.rs:42:22
|
42 | #[derive(FromZeroes, FromBytes)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `FromBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error: only C-like enums can implement FromZeroes
--> tests/ui-msrv/enum.rs:52:1
|
52 | / enum FromZeroes1 {
53 | | A(u8),
54 | | }
| |_^
error: only C-like enums can implement FromZeroes
--> tests/ui-msrv/enum.rs:57:1
|
57 | / enum FromZeroes2 {
58 | | A,
59 | | B(u8),
60 | | }
| |_^
error: FromZeroes only supported on enums with a variant that has a discriminant of `0`
--> tests/ui-msrv/enum.rs:63:1
|
63 | / enum FromZeroes3 {
64 | | A = 1,
65 | | B,
66 | | }
| |_^
error: FromBytes requires repr of "u8", "u16", "i8", or "i16"
--> tests/ui-msrv/enum.rs:73:8
|
73 | #[repr(C)]
| ^
error: FromBytes requires repr of "u8", "u16", "i8", or "i16"
--> tests/ui-msrv/enum.rs:79:8
|
79 | #[repr(usize)]
| ^^^^^
error: FromBytes requires repr of "u8", "u16", "i8", or "i16"
--> tests/ui-msrv/enum.rs:85:8
|
85 | #[repr(isize)]
| ^^^^^
error: FromBytes requires repr of "u8", "u16", "i8", or "i16"
--> tests/ui-msrv/enum.rs:91:8
|
91 | #[repr(u32)]
| ^^^
error: FromBytes requires repr of "u8", "u16", "i8", or "i16"
--> tests/ui-msrv/enum.rs:97:8
|
97 | #[repr(i32)]
| ^^^
error: FromBytes requires repr of "u8", "u16", "i8", or "i16"
--> tests/ui-msrv/enum.rs:103:8
|
103 | #[repr(u64)]
| ^^^
error: FromBytes requires repr of "u8", "u16", "i8", or "i16"
--> tests/ui-msrv/enum.rs:109:8
|
109 | #[repr(i64)]
| ^^^
error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1)))
--> tests/ui-msrv/enum.rs:119:8
|
119 | #[repr(C)]
| ^
error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1)))
--> tests/ui-msrv/enum.rs:125:8
|
125 | #[repr(u16)]
| ^^^
error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1)))
--> tests/ui-msrv/enum.rs:131:8
|
131 | #[repr(i16)]
| ^^^
error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1)))
--> tests/ui-msrv/enum.rs:137:8
|
137 | #[repr(u32)]
| ^^^
error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1)))
--> tests/ui-msrv/enum.rs:143:8
|
143 | #[repr(i32)]
| ^^^
error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1)))
--> tests/ui-msrv/enum.rs:149:8
|
149 | #[repr(u64)]
| ^^^
error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1)))
--> tests/ui-msrv/enum.rs:155:8
|
155 | #[repr(i64)]
| ^^^
error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1)))
--> tests/ui-msrv/enum.rs:161:8
|
161 | #[repr(usize)]
| ^^^^^
error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1)))
--> tests/ui-msrv/enum.rs:167:8
|
167 | #[repr(isize)]
| ^^^^^
error: cannot derive Unaligned with repr(align(N > 1))
--> tests/ui-msrv/enum.rs:173:12
|
173 | #[repr(u8, align(2))]
| ^^^^^^^^
error: cannot derive Unaligned with repr(align(N > 1))
--> tests/ui-msrv/enum.rs:179:12
|
179 | #[repr(i8, align(2))]
| ^^^^^^^^
error: cannot derive Unaligned with repr(align(N > 1))
--> tests/ui-msrv/enum.rs:185:18
|
185 | #[repr(align(1), align(2))]
| ^^^^^^^^
error: cannot derive Unaligned with repr(align(N > 1))
--> tests/ui-msrv/enum.rs:191:8
|
191 | #[repr(align(2), align(4))]
| ^^^^^^^^
error[E0565]: meta item in `repr` must be an identifier
--> tests/ui-msrv/enum.rs:19:8
|
19 | #[repr("foo")]
| ^^^^^
error[E0552]: unrecognized representation hint
--> tests/ui-msrv/enum.rs:25:8
|
25 | #[repr(foo)]
| ^^^
error[E0566]: conflicting representation hints
--> tests/ui-msrv/enum.rs:37:8
|
37 | #[repr(u8, u16)]
| ^^ ^^^
|
= note: `#[deny(conflicting_repr_hints)]` on by default
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #68585 <https://github.com/rust-lang/rust/issues/68585>

View file

@ -0,0 +1,272 @@
// 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.
#[macro_use]
extern crate zerocopy;
fn main() {}
#[derive(FromBytes)]
#[repr(u8)]
enum Foo {
Variant0,
Variant1,
Variant2,
Variant3,
Variant4,
Variant5,
Variant6,
Variant7,
Variant8,
Variant9,
Variant10,
Variant11,
Variant12,
Variant13,
Variant14,
Variant15,
Variant16,
Variant17,
Variant18,
Variant19,
Variant20,
Variant21,
Variant22,
Variant23,
Variant24,
Variant25,
Variant26,
Variant27,
Variant28,
Variant29,
Variant30,
Variant31,
Variant32,
Variant33,
Variant34,
Variant35,
Variant36,
Variant37,
Variant38,
Variant39,
Variant40,
Variant41,
Variant42,
Variant43,
Variant44,
Variant45,
Variant46,
Variant47,
Variant48,
Variant49,
Variant50,
Variant51,
Variant52,
Variant53,
Variant54,
Variant55,
Variant56,
Variant57,
Variant58,
Variant59,
Variant60,
Variant61,
Variant62,
Variant63,
Variant64,
Variant65,
Variant66,
Variant67,
Variant68,
Variant69,
Variant70,
Variant71,
Variant72,
Variant73,
Variant74,
Variant75,
Variant76,
Variant77,
Variant78,
Variant79,
Variant80,
Variant81,
Variant82,
Variant83,
Variant84,
Variant85,
Variant86,
Variant87,
Variant88,
Variant89,
Variant90,
Variant91,
Variant92,
Variant93,
Variant94,
Variant95,
Variant96,
Variant97,
Variant98,
Variant99,
Variant100,
Variant101,
Variant102,
Variant103,
Variant104,
Variant105,
Variant106,
Variant107,
Variant108,
Variant109,
Variant110,
Variant111,
Variant112,
Variant113,
Variant114,
Variant115,
Variant116,
Variant117,
Variant118,
Variant119,
Variant120,
Variant121,
Variant122,
Variant123,
Variant124,
Variant125,
Variant126,
Variant127,
Variant128,
Variant129,
Variant130,
Variant131,
Variant132,
Variant133,
Variant134,
Variant135,
Variant136,
Variant137,
Variant138,
Variant139,
Variant140,
Variant141,
Variant142,
Variant143,
Variant144,
Variant145,
Variant146,
Variant147,
Variant148,
Variant149,
Variant150,
Variant151,
Variant152,
Variant153,
Variant154,
Variant155,
Variant156,
Variant157,
Variant158,
Variant159,
Variant160,
Variant161,
Variant162,
Variant163,
Variant164,
Variant165,
Variant166,
Variant167,
Variant168,
Variant169,
Variant170,
Variant171,
Variant172,
Variant173,
Variant174,
Variant175,
Variant176,
Variant177,
Variant178,
Variant179,
Variant180,
Variant181,
Variant182,
Variant183,
Variant184,
Variant185,
Variant186,
Variant187,
Variant188,
Variant189,
Variant190,
Variant191,
Variant192,
Variant193,
Variant194,
Variant195,
Variant196,
Variant197,
Variant198,
Variant199,
Variant200,
Variant201,
Variant202,
Variant203,
Variant204,
Variant205,
Variant206,
Variant207,
Variant208,
Variant209,
Variant210,
Variant211,
Variant212,
Variant213,
Variant214,
Variant215,
Variant216,
Variant217,
Variant218,
Variant219,
Variant220,
Variant221,
Variant222,
Variant223,
Variant224,
Variant225,
Variant226,
Variant227,
Variant228,
Variant229,
Variant230,
Variant231,
Variant232,
Variant233,
Variant234,
Variant235,
Variant236,
Variant237,
Variant238,
Variant239,
Variant240,
Variant241,
Variant242,
Variant243,
Variant244,
Variant245,
Variant246,
Variant247,
Variant248,
Variant249,
Variant250,
Variant251,
Variant252,
Variant253,
Variant254,
}

View file

@ -0,0 +1,11 @@
error: FromBytes only supported on repr(u8) enum with 256 variants
--> tests/ui-msrv/enum_from_bytes_u8_too_few.rs:15:1
|
15 | / #[repr(u8)]
16 | | enum Foo {
17 | | Variant0,
18 | | Variant1,
... |
271 | | Variant254,
272 | | }
| |_^

View file

@ -0,0 +1,75 @@
// 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.
#[macro_use]
extern crate zerocopy;
#[path = "../util.rs"]
mod util;
use self::util::{NotZerocopy, AU16};
use zerocopy::KnownLayout;
fn main() {}
// These tests cause errors which are generated by a later compilation pass than
// the other errors we generate, and so if they're compiled in the same file,
// the compiler will never get to that pass, and so we won't get the errors.
//
// FromZeroes errors
//
#[derive(FromZeroes)]
struct FromZeroes1 {
value: NotZerocopy,
}
//
// FromBytes errors
//
#[derive(FromBytes)]
struct FromBytes1 {
value: NotZerocopy,
}
//
// AsBytes errors
//
#[derive(AsBytes)]
#[repr(C)]
struct AsBytes1 {
value: NotZerocopy,
}
//
// Unaligned errors
//
#[derive(Unaligned)]
#[repr(C)]
struct Unaligned1 {
aligned: AU16,
}
// This specifically tests a bug we had in an old version of the code in which
// the trait bound would only be enforced for the first field's type.
#[derive(Unaligned)]
#[repr(C)]
struct Unaligned2 {
unaligned: u8,
aligned: AU16,
}
#[derive(Unaligned)]
#[repr(transparent)]
struct Unaligned3 {
aligned: AU16,
}

View file

@ -0,0 +1,74 @@
warning: unused import: `zerocopy::KnownLayout`
--> tests/ui-msrv/late_compile_pass.rs:16:5
|
16 | use zerocopy::KnownLayout;
| ^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(unused_imports)]` on by default
error[E0277]: the trait bound `NotZerocopy: FromZeroes` is not satisfied
--> tests/ui-msrv/late_compile_pass.rs:28:10
|
28 | #[derive(FromZeroes)]
| ^^^^^^^^^^ the trait `FromZeroes` is not implemented for `NotZerocopy`
|
= help: see issue #48214
= note: this error originates in the derive macro `FromZeroes` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `NotZerocopy: FromBytes` is not satisfied
--> tests/ui-msrv/late_compile_pass.rs:37:10
|
37 | #[derive(FromBytes)]
| ^^^^^^^^^ the trait `FromBytes` is not implemented for `NotZerocopy`
|
= help: see issue #48214
= note: this error originates in the derive macro `FromBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `FromBytes1: FromZeroes` is not satisfied
--> tests/ui-msrv/late_compile_pass.rs:37:10
|
37 | #[derive(FromBytes)]
| ^^^^^^^^^ the trait `FromZeroes` is not implemented for `FromBytes1`
|
note: required by a bound in `FromBytes`
--> $WORKSPACE/src/lib.rs
|
| pub unsafe trait FromBytes: FromZeroes {
| ^^^^^^^^^^ required by this bound in `FromBytes`
= note: this error originates in the derive macro `FromBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `NotZerocopy: AsBytes` is not satisfied
--> tests/ui-msrv/late_compile_pass.rs:46:10
|
46 | #[derive(AsBytes)]
| ^^^^^^^ the trait `AsBytes` is not implemented for `NotZerocopy`
|
= help: see issue #48214
= note: this error originates in the derive macro `AsBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `AU16: Unaligned` is not satisfied
--> tests/ui-msrv/late_compile_pass.rs:56:10
|
56 | #[derive(Unaligned)]
| ^^^^^^^^^ the trait `Unaligned` is not implemented for `AU16`
|
= help: see issue #48214
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `AU16: Unaligned` is not satisfied
--> tests/ui-msrv/late_compile_pass.rs:64:10
|
64 | #[derive(Unaligned)]
| ^^^^^^^^^ the trait `Unaligned` is not implemented for `AU16`
|
= help: see issue #48214
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `AU16: Unaligned` is not satisfied
--> tests/ui-msrv/late_compile_pass.rs:71:10
|
71 | #[derive(Unaligned)]
| ^^^^^^^^^ the trait `Unaligned` is not implemented for `AU16`
|
= help: see issue #48214
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)

View file

@ -0,0 +1,61 @@
// Copyright 2023 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.
extern crate zerocopy;
use zerocopy::KnownLayout;
fn main() {}
// These tests cause errors which are generated by a later compilation pass than
// the other errors we generate, and so if they're compiled in the same file,
// the compiler will never get to that pass, and so we won't get the errors.
//
// KnownLayout errors
//
fn assert_kl<T: ?Sized + KnownLayout>(_: &T) {}
// | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
// | N | Y | N | N | KL04 |
#[derive(KnownLayout)]
struct KL04<T: ?Sized>(u8, T);
fn test_kl04<T: ?Sized>(kl: &KL04<T>) {
assert_kl(kl);
}
// | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
// | N | Y | Y | N | KL06 |
#[derive(KnownLayout)]
struct KL06<T: ?Sized + KnownLayout>(u8, T);
fn test_kl06<T: ?Sized + KnownLayout>(kl: &KL06<T>) {
assert_kl(kl);
}
// | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
// | Y | Y | N | N | KL12 |
#[derive(KnownLayout)]
#[repr(C)]
struct KL12<T: ?Sized>(u8, T);
fn test_kl12<T: ?Sized>(kl: &KL12<T>) {
assert_kl(kl)
}
// | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
// | Y | Y | N | Y | KL13 |
#[derive(KnownLayout)]
#[repr(C)]
struct KL13<T>(u8, T);
fn test_kl13<T>(t: T) -> impl KnownLayout {
KL13(0u8, t)
}

View file

@ -0,0 +1,104 @@
error[E0277]: the trait bound `T: KnownLayout` is not satisfied
--> tests/ui-msrv/mid_compile_pass.rs:59:26
|
59 | fn test_kl13<T>(t: T) -> impl KnownLayout {
| ^^^^^^^^^^^^^^^^ the trait `KnownLayout` is not implemented for `T`
|
note: required because of the requirements on the impl of `KnownLayout` for `KL13<T>`
--> tests/ui-msrv/mid_compile_pass.rs:55:10
|
55 | #[derive(KnownLayout)]
| ^^^^^^^^^^^
= note: this error originates in the derive macro `KnownLayout` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider restricting type parameter `T`
|
59 | fn test_kl13<T: zerocopy::KnownLayout>(t: T) -> impl KnownLayout {
| +++++++++++++++++++++++
error[E0277]: the size for values of type `T` cannot be known at compilation time
--> tests/ui-msrv/mid_compile_pass.rs:31:15
|
30 | fn test_kl04<T: ?Sized>(kl: &KL04<T>) {
| - this type parameter needs to be `std::marker::Sized`
31 | assert_kl(kl);
| --------- ^^ doesn't have a size known at compile-time
| |
| required by a bound introduced by this call
|
note: required because it appears within the type `KL04<T>`
--> tests/ui-msrv/mid_compile_pass.rs:28:8
|
28 | struct KL04<T: ?Sized>(u8, T);
| ^^^^
note: required because of the requirements on the impl of `KnownLayout` for `KL04<T>`
--> tests/ui-msrv/mid_compile_pass.rs:27:10
|
27 | #[derive(KnownLayout)]
| ^^^^^^^^^^^
note: required by a bound in `assert_kl`
--> tests/ui-msrv/mid_compile_pass.rs:23:26
|
23 | fn assert_kl<T: ?Sized + KnownLayout>(_: &T) {}
| ^^^^^^^^^^^ required by this bound in `assert_kl`
= note: this error originates in the derive macro `KnownLayout` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider removing the `?Sized` bound to make the type parameter `Sized`
|
30 - fn test_kl04<T: ?Sized>(kl: &KL04<T>) {
30 + fn test_kl04<T>(kl: &KL04<T>) {
|
error[E0277]: the size for values of type `T` cannot be known at compilation time
--> tests/ui-msrv/mid_compile_pass.rs:40:15
|
39 | fn test_kl06<T: ?Sized + KnownLayout>(kl: &KL06<T>) {
| - this type parameter needs to be `std::marker::Sized`
40 | assert_kl(kl);
| --------- ^^ doesn't have a size known at compile-time
| |
| required by a bound introduced by this call
|
note: required because it appears within the type `KL06<T>`
--> tests/ui-msrv/mid_compile_pass.rs:37:8
|
37 | struct KL06<T: ?Sized + KnownLayout>(u8, T);
| ^^^^
note: required because of the requirements on the impl of `KnownLayout` for `KL06<T>`
--> tests/ui-msrv/mid_compile_pass.rs:36:10
|
36 | #[derive(KnownLayout)]
| ^^^^^^^^^^^
note: required by a bound in `assert_kl`
--> tests/ui-msrv/mid_compile_pass.rs:23:26
|
23 | fn assert_kl<T: ?Sized + KnownLayout>(_: &T) {}
| ^^^^^^^^^^^ required by this bound in `assert_kl`
= note: this error originates in the derive macro `KnownLayout` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider removing the `?Sized` bound to make the type parameter `Sized`
|
39 - fn test_kl06<T: ?Sized + KnownLayout>(kl: &KL06<T>) {
39 + fn test_kl06<T: KnownLayout>(kl: &KL06<T>) {
|
error[E0277]: the trait bound `T: KnownLayout` is not satisfied
--> tests/ui-msrv/mid_compile_pass.rs:50:15
|
50 | assert_kl(kl)
| --------- ^^ the trait `KnownLayout` is not implemented for `T`
| |
| required by a bound introduced by this call
|
note: required because of the requirements on the impl of `KnownLayout` for `KL12<T>`
--> tests/ui-msrv/mid_compile_pass.rs:45:10
|
45 | #[derive(KnownLayout)]
| ^^^^^^^^^^^
note: required by a bound in `assert_kl`
--> tests/ui-msrv/mid_compile_pass.rs:23:26
|
23 | fn assert_kl<T: ?Sized + KnownLayout>(_: &T) {}
| ^^^^^^^^^^^ required by this bound in `assert_kl`
= note: this error originates in the derive macro `KnownLayout` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider further restricting this bound
|
49 | fn test_kl12<T: ?Sized + zerocopy::KnownLayout>(kl: &KL12<T>) {
| +++++++++++++++++++++++

View file

@ -0,0 +1,99 @@
// 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.
#[macro_use]
extern crate zerocopy;
#[path = "../util.rs"]
mod util;
use zerocopy::KnownLayout;
use self::util::AU16;
fn main() {}
//
// KnownLayout errors
//
struct NotKnownLayout;
struct NotKnownLayoutDst([u8]);
// | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
// | N | N | N | N | KL00 |
#[derive(KnownLayout)]
struct KL00(u8, NotKnownLayoutDst);
// | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
// | N | N | Y | N | KL02 |
#[derive(KnownLayout)]
struct KL02(u8, [u8]);
// | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
// | Y | N | N | N | KL08 |
#[derive(KnownLayout)]
#[repr(C)]
struct KL08(u8, NotKnownLayoutDst);
// | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
// | Y | N | N | Y | KL09 |
#[derive(KnownLayout)]
#[repr(C)]
struct KL09(NotKnownLayout, NotKnownLayout);
//
// AsBytes errors
//
#[derive(AsBytes)]
#[repr(C)]
struct AsBytes1<T>(T);
#[derive(AsBytes)]
#[repr(C)]
struct AsBytes2 {
foo: u8,
bar: AU16,
}
#[derive(AsBytes)]
#[repr(C, packed(2))]
struct AsBytes3 {
foo: u8,
// We'd prefer to use AU64 here, but you can't use aligned types in
// packed structs.
bar: u64,
}
//
// Unaligned errors
//
#[derive(Unaligned)]
#[repr(C, align(2))]
struct Unaligned1;
#[derive(Unaligned)]
#[repr(transparent, align(2))]
struct Unaligned2 {
foo: u8,
}
#[derive(Unaligned)]
#[repr(packed, align(2))]
struct Unaligned3;
#[derive(Unaligned)]
#[repr(align(1), align(2))]
struct Unaligned4;
#[derive(Unaligned)]
#[repr(align(2), align(4))]
struct Unaligned5;

View file

@ -0,0 +1,113 @@
error: unsupported on generic structs that are not repr(transparent) or repr(packed)
--> tests/ui-msrv/struct.rs:55:10
|
55 | #[derive(AsBytes)]
| ^^^^^^^
|
= note: this error originates in the derive macro `AsBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error: cannot derive Unaligned with repr(align(N > 1))
--> tests/ui-msrv/struct.rs:80:11
|
80 | #[repr(C, align(2))]
| ^^^^^^^^
error: cannot derive Unaligned with repr(align(N > 1))
--> tests/ui-msrv/struct.rs:84:21
|
84 | #[repr(transparent, align(2))]
| ^^^^^^^^
error: cannot derive Unaligned with repr(align(N > 1))
--> tests/ui-msrv/struct.rs:90:16
|
90 | #[repr(packed, align(2))]
| ^^^^^^^^
error: cannot derive Unaligned with repr(align(N > 1))
--> tests/ui-msrv/struct.rs:94:18
|
94 | #[repr(align(1), align(2))]
| ^^^^^^^^
error: cannot derive Unaligned with repr(align(N > 1))
--> tests/ui-msrv/struct.rs:98:8
|
98 | #[repr(align(2), align(4))]
| ^^^^^^^^
error[E0692]: transparent struct cannot have other repr hints
--> tests/ui-msrv/struct.rs:84:8
|
84 | #[repr(transparent, align(2))]
| ^^^^^^^^^^^ ^^^^^^^^
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
--> tests/ui-msrv/struct.rs:31:10
|
31 | #[derive(KnownLayout)]
| ^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: within `KL00`, the trait `Sized` is not implemented for `[u8]`
note: required because it appears within the type `KL00`
--> tests/ui-msrv/struct.rs:32:8
|
32 | struct KL00(u8, NotKnownLayoutDst);
| ^^^^
= help: see issue #48214
= note: this error originates in the derive macro `KnownLayout` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
--> tests/ui-msrv/struct.rs:36:10
|
36 | #[derive(KnownLayout)]
| ^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: within `KL02`, the trait `Sized` is not implemented for `[u8]`
note: required because it appears within the type `KL02`
--> tests/ui-msrv/struct.rs:37:8
|
37 | struct KL02(u8, [u8]);
| ^^^^
= help: see issue #48214
= note: this error originates in the derive macro `KnownLayout` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `NotKnownLayoutDst: KnownLayout` is not satisfied
--> tests/ui-msrv/struct.rs:41:10
|
41 | #[derive(KnownLayout)]
| ^^^^^^^^^^^ the trait `KnownLayout` is not implemented for `NotKnownLayoutDst`
|
= help: see issue #48214
= note: this error originates in the derive macro `KnownLayout` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `NotKnownLayout: KnownLayout` is not satisfied
--> tests/ui-msrv/struct.rs:47:10
|
47 | #[derive(KnownLayout)]
| ^^^^^^^^^^^ the trait `KnownLayout` is not implemented for `NotKnownLayout`
|
= help: see issue #48214
= note: this error originates in the derive macro `KnownLayout` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `HasPadding<AsBytes2, true>: ShouldBe<false>` is not satisfied
--> tests/ui-msrv/struct.rs:59:10
|
59 | #[derive(AsBytes)]
| ^^^^^^^ the trait `ShouldBe<false>` is not implemented for `HasPadding<AsBytes2, true>`
|
= help: the following implementations were found:
<HasPadding<T, VALUE> as ShouldBe<VALUE>>
= help: see issue #48214
= note: this error originates in the derive macro `AsBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `HasPadding<AsBytes3, true>: ShouldBe<false>` is not satisfied
--> tests/ui-msrv/struct.rs:66:10
|
66 | #[derive(AsBytes)]
| ^^^^^^^ the trait `ShouldBe<false>` is not implemented for `HasPadding<AsBytes3, true>`
|
= help: the following implementations were found:
<HasPadding<T, VALUE> as ShouldBe<VALUE>>
= help: see issue #48214
= note: this error originates in the derive macro `AsBytes` (in Nightly builds, run with -Z macro-backtrace for more info)

View file

@ -0,0 +1,73 @@
// 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.
#[macro_use]
extern crate zerocopy;
#[path = "../util.rs"]
mod util;
use self::util::AU16;
use std::mem::ManuallyDrop;
fn main() {}
//
// AsBytes errors
//
#[derive(AsBytes)]
#[repr(C)]
union AsBytes1<T> {
foo: ManuallyDrop<T>,
}
#[derive(AsBytes)]
#[repr(C)]
union AsBytes2 {
foo: u8,
bar: [u8; 2],
}
//
// Unaligned errors
//
#[derive(Unaligned)]
#[repr(C, align(2))]
union Unaligned1 {
foo: i16,
bar: AU16,
}
// Transparent unions are unstable; see issue #60405
// <https://github.com/rust-lang/rust/issues/60405> for more information.
// #[derive(Unaligned)]
// #[repr(transparent, align(2))]
// union Unaligned2 {
// foo: u8,
// }
#[derive(Unaligned)]
#[repr(packed, align(2))]
union Unaligned3 {
foo: u8,
}
#[derive(Unaligned)]
#[repr(align(1), align(2))]
struct Unaligned4 {
foo: u8,
}
#[derive(Unaligned)]
#[repr(align(2), align(4))]
struct Unaligned5 {
foo: u8,
}

View file

@ -0,0 +1,42 @@
error: unsupported on types with type parameters
--> tests/ui-msrv/union.rs:24:10
|
24 | #[derive(AsBytes)]
| ^^^^^^^
|
= note: this error originates in the derive macro `AsBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error: cannot derive Unaligned with repr(align(N > 1))
--> tests/ui-msrv/union.rs:42:11
|
42 | #[repr(C, align(2))]
| ^^^^^^^^
error: cannot derive Unaligned with repr(align(N > 1))
--> tests/ui-msrv/union.rs:58:16
|
58 | #[repr(packed, align(2))]
| ^^^^^^^^
error: cannot derive Unaligned with repr(align(N > 1))
--> tests/ui-msrv/union.rs:64:18
|
64 | #[repr(align(1), align(2))]
| ^^^^^^^^
error: cannot derive Unaligned with repr(align(N > 1))
--> tests/ui-msrv/union.rs:70:8
|
70 | #[repr(align(2), align(4))]
| ^^^^^^^^
error[E0277]: the trait bound `HasPadding<AsBytes2, true>: ShouldBe<false>` is not satisfied
--> tests/ui-msrv/union.rs:30:10
|
30 | #[derive(AsBytes)]
| ^^^^^^^ the trait `ShouldBe<false>` is not implemented for `HasPadding<AsBytes2, true>`
|
= help: the following implementations were found:
<HasPadding<T, VALUE> as ShouldBe<VALUE>>
= help: see issue #48214
= note: this error originates in the derive macro `AsBytes` (in Nightly builds, run with -Z macro-backtrace for more info)

View file

@ -0,0 +1,40 @@
// 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.
extern crate zerocopy;
#[path = "../util.rs"]
mod util;
use core::marker::PhantomData;
use {
static_assertions::assert_impl_all,
zerocopy::{AsBytes, FromBytes, FromZeroes, Unaligned},
};
use self::util::NotZerocopy;
fn main() {}
// Test generic transparent structs
#[derive(AsBytes, FromZeroes, FromBytes, Unaligned)]
#[repr(transparent)]
struct TransparentStruct<T> {
inner: T,
_phantom: PhantomData<()>,
}
// It should be legal to derive these traits on a transparent struct, but it
// must also ensure the traits are only implemented when the inner type
// implements them.
assert_impl_all!(TransparentStruct<NotZerocopy>: FromZeroes);
assert_impl_all!(TransparentStruct<NotZerocopy>: FromBytes);
assert_impl_all!(TransparentStruct<NotZerocopy>: AsBytes);
assert_impl_all!(TransparentStruct<NotZerocopy>: Unaligned);

View file

@ -0,0 +1,111 @@
error[E0277]: the trait bound `NotZerocopy: FromZeroes` is not satisfied
--> tests/ui-nightly/derive_transparent.rs:37:18
|
37 | assert_impl_all!(TransparentStruct<NotZerocopy>: FromZeroes);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `FromZeroes` is not implemented for `NotZerocopy`
|
= help: the following other types implement trait `FromZeroes`:
bool
char
isize
i8
i16
i32
i64
i128
and $N others
note: required for `TransparentStruct<NotZerocopy>` to implement `FromZeroes`
--> tests/ui-nightly/derive_transparent.rs:27:19
|
27 | #[derive(AsBytes, FromZeroes, FromBytes, Unaligned)]
| ^^^^^^^^^^ unsatisfied trait bound introduced in this `derive` macro
note: required by a bound in `_::{closure#0}::assert_impl_all`
--> tests/ui-nightly/derive_transparent.rs:37:1
|
37 | assert_impl_all!(TransparentStruct<NotZerocopy>: FromZeroes);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `assert_impl_all`
= note: this error originates in the derive macro `FromZeroes` which comes from the expansion of the macro `assert_impl_all` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `NotZerocopy: FromBytes` is not satisfied
--> tests/ui-nightly/derive_transparent.rs:38:18
|
38 | assert_impl_all!(TransparentStruct<NotZerocopy>: FromBytes);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `FromBytes` is not implemented for `NotZerocopy`
|
= help: the following other types implement trait `FromBytes`:
isize
i8
i16
i32
i64
i128
usize
u8
and $N others
note: required for `TransparentStruct<NotZerocopy>` to implement `FromBytes`
--> tests/ui-nightly/derive_transparent.rs:27:31
|
27 | #[derive(AsBytes, FromZeroes, FromBytes, Unaligned)]
| ^^^^^^^^^ unsatisfied trait bound introduced in this `derive` macro
note: required by a bound in `_::{closure#0}::assert_impl_all`
--> tests/ui-nightly/derive_transparent.rs:38:1
|
38 | assert_impl_all!(TransparentStruct<NotZerocopy>: FromBytes);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `assert_impl_all`
= note: this error originates in the derive macro `FromBytes` which comes from the expansion of the macro `assert_impl_all` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `NotZerocopy: AsBytes` is not satisfied
--> tests/ui-nightly/derive_transparent.rs:39:18
|
39 | assert_impl_all!(TransparentStruct<NotZerocopy>: AsBytes);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `AsBytes` is not implemented for `NotZerocopy`
|
= help: the following other types implement trait `AsBytes`:
bool
char
isize
i8
i16
i32
i64
i128
and $N others
note: required for `TransparentStruct<NotZerocopy>` to implement `AsBytes`
--> tests/ui-nightly/derive_transparent.rs:27:10
|
27 | #[derive(AsBytes, FromZeroes, FromBytes, Unaligned)]
| ^^^^^^^ unsatisfied trait bound introduced in this `derive` macro
note: required by a bound in `_::{closure#0}::assert_impl_all`
--> tests/ui-nightly/derive_transparent.rs:39:1
|
39 | assert_impl_all!(TransparentStruct<NotZerocopy>: AsBytes);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `assert_impl_all`
= note: this error originates in the derive macro `AsBytes` which comes from the expansion of the macro `assert_impl_all` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `NotZerocopy: Unaligned` is not satisfied
--> tests/ui-nightly/derive_transparent.rs:40:18
|
40 | assert_impl_all!(TransparentStruct<NotZerocopy>: Unaligned);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Unaligned` is not implemented for `NotZerocopy`
|
= help: the following other types implement trait `Unaligned`:
bool
i8
u8
TransparentStruct<T>
U16<O>
U32<O>
U64<O>
U128<O>
and $N others
note: required for `TransparentStruct<NotZerocopy>` to implement `Unaligned`
--> tests/ui-nightly/derive_transparent.rs:27:42
|
27 | #[derive(AsBytes, FromZeroes, FromBytes, Unaligned)]
| ^^^^^^^^^ unsatisfied trait bound introduced in this `derive` macro
note: required by a bound in `_::{closure#0}::assert_impl_all`
--> tests/ui-nightly/derive_transparent.rs:40:1
|
40 | assert_impl_all!(TransparentStruct<NotZerocopy>: Unaligned);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `assert_impl_all`
= note: this error originates in the derive macro `Unaligned` which comes from the expansion of the macro `assert_impl_all` (in Nightly builds, run with -Z macro-backtrace for more info)

View file

@ -0,0 +1,194 @@
// 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.
#[macro_use]
extern crate zerocopy;
fn main() {}
//
// Generic errors
//
#[derive(FromZeroes, FromBytes)]
#[repr("foo")]
enum Generic1 {
A,
}
#[derive(FromZeroes, FromBytes)]
#[repr(foo)]
enum Generic2 {
A,
}
#[derive(FromZeroes, FromBytes)]
#[repr(transparent)]
enum Generic3 {
A,
}
#[derive(FromZeroes, FromBytes)]
#[repr(u8, u16)]
enum Generic4 {
A,
}
#[derive(FromZeroes, FromBytes)]
enum Generic5 {
A,
}
//
// FromZeroes errors
//
#[derive(FromZeroes)]
enum FromZeroes1 {
A(u8),
}
#[derive(FromZeroes)]
enum FromZeroes2 {
A,
B(u8),
}
#[derive(FromZeroes)]
enum FromZeroes3 {
A = 1,
B,
}
//
// FromBytes errors
//
#[derive(FromZeroes, FromBytes)]
#[repr(C)]
enum FromBytes1 {
A,
}
#[derive(FromZeroes, FromBytes)]
#[repr(usize)]
enum FromBytes2 {
A,
}
#[derive(FromZeroes, FromBytes)]
#[repr(isize)]
enum FromBytes3 {
A,
}
#[derive(FromZeroes, FromBytes)]
#[repr(u32)]
enum FromBytes4 {
A,
}
#[derive(FromZeroes, FromBytes)]
#[repr(i32)]
enum FromBytes5 {
A,
}
#[derive(FromZeroes, FromBytes)]
#[repr(u64)]
enum FromBytes6 {
A,
}
#[derive(FromZeroes, FromBytes)]
#[repr(i64)]
enum FromBytes7 {
A,
}
//
// Unaligned errors
//
#[derive(Unaligned)]
#[repr(C)]
enum Unaligned1 {
A,
}
#[derive(Unaligned)]
#[repr(u16)]
enum Unaligned2 {
A,
}
#[derive(Unaligned)]
#[repr(i16)]
enum Unaligned3 {
A,
}
#[derive(Unaligned)]
#[repr(u32)]
enum Unaligned4 {
A,
}
#[derive(Unaligned)]
#[repr(i32)]
enum Unaligned5 {
A,
}
#[derive(Unaligned)]
#[repr(u64)]
enum Unaligned6 {
A,
}
#[derive(Unaligned)]
#[repr(i64)]
enum Unaligned7 {
A,
}
#[derive(Unaligned)]
#[repr(usize)]
enum Unaligned8 {
A,
}
#[derive(Unaligned)]
#[repr(isize)]
enum Unaligned9 {
A,
}
#[derive(Unaligned)]
#[repr(u8, align(2))]
enum Unaligned10 {
A,
}
#[derive(Unaligned)]
#[repr(i8, align(2))]
enum Unaligned11 {
A,
}
#[derive(Unaligned)]
#[repr(align(1), align(2))]
enum Unaligned12 {
A,
}
#[derive(Unaligned)]
#[repr(align(2), align(4))]
enum Unaligned13 {
A,
}

View file

@ -0,0 +1,201 @@
error: unrecognized representation hint
--> tests/ui-nightly/enum.rs:19:8
|
19 | #[repr("foo")]
| ^^^^^
error: unrecognized representation hint
--> tests/ui-nightly/enum.rs:25:8
|
25 | #[repr(foo)]
| ^^^
error: unsupported representation for deriving FromBytes, AsBytes, or Unaligned on an enum
--> tests/ui-nightly/enum.rs:31:8
|
31 | #[repr(transparent)]
| ^^^^^^^^^^^
error: conflicting representation hints
--> tests/ui-nightly/enum.rs:37:8
|
37 | #[repr(u8, u16)]
| ^^^^^^^
error: must have a non-align #[repr(...)] attribute in order to guarantee this type's memory layout
--> tests/ui-nightly/enum.rs:42:22
|
42 | #[derive(FromZeroes, FromBytes)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `FromBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error: only C-like enums can implement FromZeroes
--> tests/ui-nightly/enum.rs:52:1
|
52 | / enum FromZeroes1 {
53 | | A(u8),
54 | | }
| |_^
error: only C-like enums can implement FromZeroes
--> tests/ui-nightly/enum.rs:57:1
|
57 | / enum FromZeroes2 {
58 | | A,
59 | | B(u8),
60 | | }
| |_^
error: FromZeroes only supported on enums with a variant that has a discriminant of `0`
--> tests/ui-nightly/enum.rs:63:1
|
63 | / enum FromZeroes3 {
64 | | A = 1,
65 | | B,
66 | | }
| |_^
error: FromBytes requires repr of "u8", "u16", "i8", or "i16"
--> tests/ui-nightly/enum.rs:73:8
|
73 | #[repr(C)]
| ^
error: FromBytes requires repr of "u8", "u16", "i8", or "i16"
--> tests/ui-nightly/enum.rs:79:8
|
79 | #[repr(usize)]
| ^^^^^
error: FromBytes requires repr of "u8", "u16", "i8", or "i16"
--> tests/ui-nightly/enum.rs:85:8
|
85 | #[repr(isize)]
| ^^^^^
error: FromBytes requires repr of "u8", "u16", "i8", or "i16"
--> tests/ui-nightly/enum.rs:91:8
|
91 | #[repr(u32)]
| ^^^
error: FromBytes requires repr of "u8", "u16", "i8", or "i16"
--> tests/ui-nightly/enum.rs:97:8
|
97 | #[repr(i32)]
| ^^^
error: FromBytes requires repr of "u8", "u16", "i8", or "i16"
--> tests/ui-nightly/enum.rs:103:8
|
103 | #[repr(u64)]
| ^^^
error: FromBytes requires repr of "u8", "u16", "i8", or "i16"
--> tests/ui-nightly/enum.rs:109:8
|
109 | #[repr(i64)]
| ^^^
error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1)))
--> tests/ui-nightly/enum.rs:119:8
|
119 | #[repr(C)]
| ^
error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1)))
--> tests/ui-nightly/enum.rs:125:8
|
125 | #[repr(u16)]
| ^^^
error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1)))
--> tests/ui-nightly/enum.rs:131:8
|
131 | #[repr(i16)]
| ^^^
error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1)))
--> tests/ui-nightly/enum.rs:137:8
|
137 | #[repr(u32)]
| ^^^
error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1)))
--> tests/ui-nightly/enum.rs:143:8
|
143 | #[repr(i32)]
| ^^^
error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1)))
--> tests/ui-nightly/enum.rs:149:8
|
149 | #[repr(u64)]
| ^^^
error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1)))
--> tests/ui-nightly/enum.rs:155:8
|
155 | #[repr(i64)]
| ^^^
error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1)))
--> tests/ui-nightly/enum.rs:161:8
|
161 | #[repr(usize)]
| ^^^^^
error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1)))
--> tests/ui-nightly/enum.rs:167:8
|
167 | #[repr(isize)]
| ^^^^^
error: cannot derive Unaligned with repr(align(N > 1))
--> tests/ui-nightly/enum.rs:173:12
|
173 | #[repr(u8, align(2))]
| ^^^^^^^^
error: cannot derive Unaligned with repr(align(N > 1))
--> tests/ui-nightly/enum.rs:179:12
|
179 | #[repr(i8, align(2))]
| ^^^^^^^^
error: cannot derive Unaligned with repr(align(N > 1))
--> tests/ui-nightly/enum.rs:185:18
|
185 | #[repr(align(1), align(2))]
| ^^^^^^^^
error: cannot derive Unaligned with repr(align(N > 1))
--> tests/ui-nightly/enum.rs:191:8
|
191 | #[repr(align(2), align(4))]
| ^^^^^^^^
error[E0565]: meta item in `repr` must be an identifier
--> tests/ui-nightly/enum.rs:19:8
|
19 | #[repr("foo")]
| ^^^^^
error[E0552]: unrecognized representation hint
--> tests/ui-nightly/enum.rs:25:8
|
25 | #[repr(foo)]
| ^^^
|
= help: valid reprs are `Rust` (default), `C`, `align`, `packed`, `transparent`, `simd`, `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize`
error[E0566]: conflicting representation hints
--> tests/ui-nightly/enum.rs:37:8
|
37 | #[repr(u8, u16)]
| ^^ ^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #68585 <https://github.com/rust-lang/rust/issues/68585>
= note: `#[deny(conflicting_repr_hints)]` on by default

View file

@ -0,0 +1,272 @@
// 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.
#[macro_use]
extern crate zerocopy;
fn main() {}
#[derive(FromBytes)]
#[repr(u8)]
enum Foo {
Variant0,
Variant1,
Variant2,
Variant3,
Variant4,
Variant5,
Variant6,
Variant7,
Variant8,
Variant9,
Variant10,
Variant11,
Variant12,
Variant13,
Variant14,
Variant15,
Variant16,
Variant17,
Variant18,
Variant19,
Variant20,
Variant21,
Variant22,
Variant23,
Variant24,
Variant25,
Variant26,
Variant27,
Variant28,
Variant29,
Variant30,
Variant31,
Variant32,
Variant33,
Variant34,
Variant35,
Variant36,
Variant37,
Variant38,
Variant39,
Variant40,
Variant41,
Variant42,
Variant43,
Variant44,
Variant45,
Variant46,
Variant47,
Variant48,
Variant49,
Variant50,
Variant51,
Variant52,
Variant53,
Variant54,
Variant55,
Variant56,
Variant57,
Variant58,
Variant59,
Variant60,
Variant61,
Variant62,
Variant63,
Variant64,
Variant65,
Variant66,
Variant67,
Variant68,
Variant69,
Variant70,
Variant71,
Variant72,
Variant73,
Variant74,
Variant75,
Variant76,
Variant77,
Variant78,
Variant79,
Variant80,
Variant81,
Variant82,
Variant83,
Variant84,
Variant85,
Variant86,
Variant87,
Variant88,
Variant89,
Variant90,
Variant91,
Variant92,
Variant93,
Variant94,
Variant95,
Variant96,
Variant97,
Variant98,
Variant99,
Variant100,
Variant101,
Variant102,
Variant103,
Variant104,
Variant105,
Variant106,
Variant107,
Variant108,
Variant109,
Variant110,
Variant111,
Variant112,
Variant113,
Variant114,
Variant115,
Variant116,
Variant117,
Variant118,
Variant119,
Variant120,
Variant121,
Variant122,
Variant123,
Variant124,
Variant125,
Variant126,
Variant127,
Variant128,
Variant129,
Variant130,
Variant131,
Variant132,
Variant133,
Variant134,
Variant135,
Variant136,
Variant137,
Variant138,
Variant139,
Variant140,
Variant141,
Variant142,
Variant143,
Variant144,
Variant145,
Variant146,
Variant147,
Variant148,
Variant149,
Variant150,
Variant151,
Variant152,
Variant153,
Variant154,
Variant155,
Variant156,
Variant157,
Variant158,
Variant159,
Variant160,
Variant161,
Variant162,
Variant163,
Variant164,
Variant165,
Variant166,
Variant167,
Variant168,
Variant169,
Variant170,
Variant171,
Variant172,
Variant173,
Variant174,
Variant175,
Variant176,
Variant177,
Variant178,
Variant179,
Variant180,
Variant181,
Variant182,
Variant183,
Variant184,
Variant185,
Variant186,
Variant187,
Variant188,
Variant189,
Variant190,
Variant191,
Variant192,
Variant193,
Variant194,
Variant195,
Variant196,
Variant197,
Variant198,
Variant199,
Variant200,
Variant201,
Variant202,
Variant203,
Variant204,
Variant205,
Variant206,
Variant207,
Variant208,
Variant209,
Variant210,
Variant211,
Variant212,
Variant213,
Variant214,
Variant215,
Variant216,
Variant217,
Variant218,
Variant219,
Variant220,
Variant221,
Variant222,
Variant223,
Variant224,
Variant225,
Variant226,
Variant227,
Variant228,
Variant229,
Variant230,
Variant231,
Variant232,
Variant233,
Variant234,
Variant235,
Variant236,
Variant237,
Variant238,
Variant239,
Variant240,
Variant241,
Variant242,
Variant243,
Variant244,
Variant245,
Variant246,
Variant247,
Variant248,
Variant249,
Variant250,
Variant251,
Variant252,
Variant253,
Variant254,
}

View file

@ -0,0 +1,11 @@
error: FromBytes only supported on repr(u8) enum with 256 variants
--> tests/ui-nightly/enum_from_bytes_u8_too_few.rs:15:1
|
15 | / #[repr(u8)]
16 | | enum Foo {
17 | | Variant0,
18 | | Variant1,
... |
271 | | Variant254,
272 | | }
| |_^

View file

@ -0,0 +1,75 @@
// 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.
#[macro_use]
extern crate zerocopy;
#[path = "../util.rs"]
mod util;
use self::util::{NotZerocopy, AU16};
use zerocopy::KnownLayout;
fn main() {}
// These tests cause errors which are generated by a later compilation pass than
// the other errors we generate, and so if they're compiled in the same file,
// the compiler will never get to that pass, and so we won't get the errors.
//
// FromZeroes errors
//
#[derive(FromZeroes)]
struct FromZeroes1 {
value: NotZerocopy,
}
//
// FromBytes errors
//
#[derive(FromBytes)]
struct FromBytes1 {
value: NotZerocopy,
}
//
// AsBytes errors
//
#[derive(AsBytes)]
#[repr(C)]
struct AsBytes1 {
value: NotZerocopy,
}
//
// Unaligned errors
//
#[derive(Unaligned)]
#[repr(C)]
struct Unaligned1 {
aligned: AU16,
}
// This specifically tests a bug we had in an old version of the code in which
// the trait bound would only be enforced for the first field's type.
#[derive(Unaligned)]
#[repr(C)]
struct Unaligned2 {
unaligned: u8,
aligned: AU16,
}
#[derive(Unaligned)]
#[repr(transparent)]
struct Unaligned3 {
aligned: AU16,
}

View file

@ -0,0 +1,150 @@
warning: unused import: `zerocopy::KnownLayout`
--> tests/ui-nightly/late_compile_pass.rs:16:5
|
16 | use zerocopy::KnownLayout;
| ^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(unused_imports)]` on by default
error[E0277]: the trait bound `NotZerocopy: FromZeroes` is not satisfied
--> tests/ui-nightly/late_compile_pass.rs:28:10
|
28 | #[derive(FromZeroes)]
| ^^^^^^^^^^ the trait `FromZeroes` is not implemented for `NotZerocopy`
|
= help: the following other types implement trait `FromZeroes`:
bool
char
isize
i8
i16
i32
i64
i128
and $N others
= help: see issue #48214
= help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
= note: this error originates in the derive macro `FromZeroes` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `NotZerocopy: FromBytes` is not satisfied
--> tests/ui-nightly/late_compile_pass.rs:37:10
|
37 | #[derive(FromBytes)]
| ^^^^^^^^^ the trait `FromBytes` is not implemented for `NotZerocopy`
|
= help: the following other types implement trait `FromBytes`:
isize
i8
i16
i32
i64
i128
usize
u8
and $N others
= help: see issue #48214
= help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
= note: this error originates in the derive macro `FromBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `FromBytes1: FromZeroes` is not satisfied
--> tests/ui-nightly/late_compile_pass.rs:37:10
|
37 | #[derive(FromBytes)]
| ^^^^^^^^^ the trait `FromZeroes` is not implemented for `FromBytes1`
|
= help: the following other types implement trait `FromZeroes`:
bool
char
isize
i8
i16
i32
i64
i128
and $N others
note: required by a bound in `FromBytes`
--> $WORKSPACE/src/lib.rs
|
| pub unsafe trait FromBytes: FromZeroes {
| ^^^^^^^^^^ required by this bound in `FromBytes`
= note: this error originates in the derive macro `FromBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `NotZerocopy: AsBytes` is not satisfied
--> tests/ui-nightly/late_compile_pass.rs:46:10
|
46 | #[derive(AsBytes)]
| ^^^^^^^ the trait `AsBytes` is not implemented for `NotZerocopy`
|
= help: the following other types implement trait `AsBytes`:
bool
char
isize
i8
i16
i32
i64
i128
and $N others
= help: see issue #48214
= help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
= note: this error originates in the derive macro `AsBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `AU16: Unaligned` is not satisfied
--> tests/ui-nightly/late_compile_pass.rs:56:10
|
56 | #[derive(Unaligned)]
| ^^^^^^^^^ the trait `Unaligned` is not implemented for `AU16`
|
= help: the following other types implement trait `Unaligned`:
bool
i8
u8
Unaligned1
Unaligned2
Unaligned3
U16<O>
U32<O>
and $N others
= help: see issue #48214
= help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `AU16: Unaligned` is not satisfied
--> tests/ui-nightly/late_compile_pass.rs:64:10
|
64 | #[derive(Unaligned)]
| ^^^^^^^^^ the trait `Unaligned` is not implemented for `AU16`
|
= help: the following other types implement trait `Unaligned`:
bool
i8
u8
Unaligned1
Unaligned2
Unaligned3
U16<O>
U32<O>
and $N others
= help: see issue #48214
= help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `AU16: Unaligned` is not satisfied
--> tests/ui-nightly/late_compile_pass.rs:71:10
|
71 | #[derive(Unaligned)]
| ^^^^^^^^^ the trait `Unaligned` is not implemented for `AU16`
|
= help: the following other types implement trait `Unaligned`:
bool
i8
u8
Unaligned1
Unaligned2
Unaligned3
U16<O>
U32<O>
and $N others
= help: see issue #48214
= help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)

View file

@ -0,0 +1,61 @@
// Copyright 2023 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.
extern crate zerocopy;
use zerocopy::KnownLayout;
fn main() {}
// These tests cause errors which are generated by a later compilation pass than
// the other errors we generate, and so if they're compiled in the same file,
// the compiler will never get to that pass, and so we won't get the errors.
//
// KnownLayout errors
//
fn assert_kl<T: ?Sized + KnownLayout>(_: &T) {}
// | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
// | N | Y | N | N | KL04 |
#[derive(KnownLayout)]
struct KL04<T: ?Sized>(u8, T);
fn test_kl04<T: ?Sized>(kl: &KL04<T>) {
assert_kl(kl);
}
// | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
// | N | Y | Y | N | KL06 |
#[derive(KnownLayout)]
struct KL06<T: ?Sized + KnownLayout>(u8, T);
fn test_kl06<T: ?Sized + KnownLayout>(kl: &KL06<T>) {
assert_kl(kl);
}
// | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
// | Y | Y | N | N | KL12 |
#[derive(KnownLayout)]
#[repr(C)]
struct KL12<T: ?Sized>(u8, T);
fn test_kl12<T: ?Sized>(kl: &KL12<T>) {
assert_kl(kl)
}
// | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
// | Y | Y | N | Y | KL13 |
#[derive(KnownLayout)]
#[repr(C)]
struct KL13<T>(u8, T);
fn test_kl13<T>(t: T) -> impl KnownLayout {
KL13(0u8, t)
}

View file

@ -0,0 +1,104 @@
error[E0277]: the trait bound `T: KnownLayout` is not satisfied
--> tests/ui-nightly/mid_compile_pass.rs:59:26
|
59 | fn test_kl13<T>(t: T) -> impl KnownLayout {
| ^^^^^^^^^^^^^^^^ the trait `KnownLayout` is not implemented for `T`
|
note: required for `KL13<T>` to implement `KnownLayout`
--> tests/ui-nightly/mid_compile_pass.rs:55:10
|
55 | #[derive(KnownLayout)]
| ^^^^^^^^^^^ unsatisfied trait bound introduced in this `derive` macro
= note: this error originates in the derive macro `KnownLayout` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider restricting type parameter `T`
|
59 | fn test_kl13<T: zerocopy::KnownLayout>(t: T) -> impl KnownLayout {
| +++++++++++++++++++++++
error[E0277]: the size for values of type `T` cannot be known at compilation time
--> tests/ui-nightly/mid_compile_pass.rs:31:15
|
30 | fn test_kl04<T: ?Sized>(kl: &KL04<T>) {
| - this type parameter needs to be `Sized`
31 | assert_kl(kl);
| --------- ^^ doesn't have a size known at compile-time
| |
| required by a bound introduced by this call
|
note: required because it appears within the type `KL04<T>`
--> tests/ui-nightly/mid_compile_pass.rs:28:8
|
28 | struct KL04<T: ?Sized>(u8, T);
| ^^^^
note: required for `KL04<T>` to implement `KnownLayout`
--> tests/ui-nightly/mid_compile_pass.rs:27:10
|
27 | #[derive(KnownLayout)]
| ^^^^^^^^^^^ unsatisfied trait bound introduced in this `derive` macro
note: required by a bound in `assert_kl`
--> tests/ui-nightly/mid_compile_pass.rs:23:26
|
23 | fn assert_kl<T: ?Sized + KnownLayout>(_: &T) {}
| ^^^^^^^^^^^ required by this bound in `assert_kl`
= note: this error originates in the derive macro `KnownLayout` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider removing the `?Sized` bound to make the type parameter `Sized`
|
30 - fn test_kl04<T: ?Sized>(kl: &KL04<T>) {
30 + fn test_kl04<T>(kl: &KL04<T>) {
|
error[E0277]: the size for values of type `T` cannot be known at compilation time
--> tests/ui-nightly/mid_compile_pass.rs:40:15
|
39 | fn test_kl06<T: ?Sized + KnownLayout>(kl: &KL06<T>) {
| - this type parameter needs to be `Sized`
40 | assert_kl(kl);
| --------- ^^ doesn't have a size known at compile-time
| |
| required by a bound introduced by this call
|
note: required because it appears within the type `KL06<T>`
--> tests/ui-nightly/mid_compile_pass.rs:37:8
|
37 | struct KL06<T: ?Sized + KnownLayout>(u8, T);
| ^^^^
note: required for `KL06<T>` to implement `KnownLayout`
--> tests/ui-nightly/mid_compile_pass.rs:36:10
|
36 | #[derive(KnownLayout)]
| ^^^^^^^^^^^ unsatisfied trait bound introduced in this `derive` macro
note: required by a bound in `assert_kl`
--> tests/ui-nightly/mid_compile_pass.rs:23:26
|
23 | fn assert_kl<T: ?Sized + KnownLayout>(_: &T) {}
| ^^^^^^^^^^^ required by this bound in `assert_kl`
= note: this error originates in the derive macro `KnownLayout` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider removing the `?Sized` bound to make the type parameter `Sized`
|
39 - fn test_kl06<T: ?Sized + KnownLayout>(kl: &KL06<T>) {
39 + fn test_kl06<T: KnownLayout>(kl: &KL06<T>) {
|
error[E0277]: the trait bound `T: KnownLayout` is not satisfied
--> tests/ui-nightly/mid_compile_pass.rs:50:15
|
50 | assert_kl(kl)
| --------- ^^ the trait `KnownLayout` is not implemented for `T`
| |
| required by a bound introduced by this call
|
note: required for `KL12<T>` to implement `KnownLayout`
--> tests/ui-nightly/mid_compile_pass.rs:45:10
|
45 | #[derive(KnownLayout)]
| ^^^^^^^^^^^ unsatisfied trait bound introduced in this `derive` macro
note: required by a bound in `assert_kl`
--> tests/ui-nightly/mid_compile_pass.rs:23:26
|
23 | fn assert_kl<T: ?Sized + KnownLayout>(_: &T) {}
| ^^^^^^^^^^^ required by this bound in `assert_kl`
= note: this error originates in the derive macro `KnownLayout` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider further restricting this bound
|
49 | fn test_kl12<T: ?Sized + zerocopy::KnownLayout>(kl: &KL12<T>) {
| +++++++++++++++++++++++

View file

@ -0,0 +1,99 @@
// 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.
#[macro_use]
extern crate zerocopy;
#[path = "../util.rs"]
mod util;
use zerocopy::KnownLayout;
use self::util::AU16;
fn main() {}
//
// KnownLayout errors
//
struct NotKnownLayout;
struct NotKnownLayoutDst([u8]);
// | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
// | N | N | N | N | KL00 |
#[derive(KnownLayout)]
struct KL00(u8, NotKnownLayoutDst);
// | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
// | N | N | Y | N | KL02 |
#[derive(KnownLayout)]
struct KL02(u8, [u8]);
// | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
// | Y | N | N | N | KL08 |
#[derive(KnownLayout)]
#[repr(C)]
struct KL08(u8, NotKnownLayoutDst);
// | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
// | Y | N | N | Y | KL09 |
#[derive(KnownLayout)]
#[repr(C)]
struct KL09(NotKnownLayout, NotKnownLayout);
//
// AsBytes errors
//
#[derive(AsBytes)]
#[repr(C)]
struct AsBytes1<T>(T);
#[derive(AsBytes)]
#[repr(C)]
struct AsBytes2 {
foo: u8,
bar: AU16,
}
#[derive(AsBytes)]
#[repr(C, packed(2))]
struct AsBytes3 {
foo: u8,
// We'd prefer to use AU64 here, but you can't use aligned types in
// packed structs.
bar: u64,
}
//
// Unaligned errors
//
#[derive(Unaligned)]
#[repr(C, align(2))]
struct Unaligned1;
#[derive(Unaligned)]
#[repr(transparent, align(2))]
struct Unaligned2 {
foo: u8,
}
#[derive(Unaligned)]
#[repr(packed, align(2))]
struct Unaligned3;
#[derive(Unaligned)]
#[repr(align(1), align(2))]
struct Unaligned4;
#[derive(Unaligned)]
#[repr(align(2), align(4))]
struct Unaligned5;

View file

@ -0,0 +1,143 @@
error: unsupported on generic structs that are not repr(transparent) or repr(packed)
--> tests/ui-nightly/struct.rs:55:10
|
55 | #[derive(AsBytes)]
| ^^^^^^^
|
= note: this error originates in the derive macro `AsBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error: cannot derive Unaligned with repr(align(N > 1))
--> tests/ui-nightly/struct.rs:80:11
|
80 | #[repr(C, align(2))]
| ^^^^^^^^
error: cannot derive Unaligned with repr(align(N > 1))
--> tests/ui-nightly/struct.rs:84:21
|
84 | #[repr(transparent, align(2))]
| ^^^^^^^^
error: cannot derive Unaligned with repr(align(N > 1))
--> tests/ui-nightly/struct.rs:90:16
|
90 | #[repr(packed, align(2))]
| ^^^^^^^^
error: cannot derive Unaligned with repr(align(N > 1))
--> tests/ui-nightly/struct.rs:94:18
|
94 | #[repr(align(1), align(2))]
| ^^^^^^^^
error: cannot derive Unaligned with repr(align(N > 1))
--> tests/ui-nightly/struct.rs:98:8
|
98 | #[repr(align(2), align(4))]
| ^^^^^^^^
error[E0692]: transparent struct cannot have other repr hints
--> tests/ui-nightly/struct.rs:84:8
|
84 | #[repr(transparent, align(2))]
| ^^^^^^^^^^^ ^^^^^^^^
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
--> tests/ui-nightly/struct.rs:31:10
|
31 | #[derive(KnownLayout)]
| ^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: within `KL00`, the trait `Sized` is not implemented for `[u8]`
note: required because it appears within the type `KL00`
--> tests/ui-nightly/struct.rs:32:8
|
32 | struct KL00(u8, NotKnownLayoutDst);
| ^^^^
= help: see issue #48214
= help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
= note: this error originates in the derive macro `KnownLayout` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
--> tests/ui-nightly/struct.rs:36:10
|
36 | #[derive(KnownLayout)]
| ^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: within `KL02`, the trait `Sized` is not implemented for `[u8]`
note: required because it appears within the type `KL02`
--> tests/ui-nightly/struct.rs:37:8
|
37 | struct KL02(u8, [u8]);
| ^^^^
= help: see issue #48214
= help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
= note: this error originates in the derive macro `KnownLayout` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `NotKnownLayoutDst: KnownLayout` is not satisfied
--> tests/ui-nightly/struct.rs:41:10
|
41 | #[derive(KnownLayout)]
| ^^^^^^^^^^^ the trait `KnownLayout` is not implemented for `NotKnownLayoutDst`
|
= help: the following other types implement trait `KnownLayout`:
bool
char
isize
i8
i16
i32
i64
i128
and $N others
= help: see issue #48214
= help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
= note: this error originates in the derive macro `KnownLayout` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `NotKnownLayout: KnownLayout` is not satisfied
--> tests/ui-nightly/struct.rs:47:10
|
47 | #[derive(KnownLayout)]
| ^^^^^^^^^^^ the trait `KnownLayout` is not implemented for `NotKnownLayout`
|
= help: the following other types implement trait `KnownLayout`:
bool
char
isize
i8
i16
i32
i64
i128
and $N others
= help: see issue #48214
= help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
= note: this error originates in the derive macro `KnownLayout` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `HasPadding<AsBytes2, true>: ShouldBe<false>` is not satisfied
--> tests/ui-nightly/struct.rs:59:10
|
59 | #[derive(AsBytes)]
| ^^^^^^^ the trait `ShouldBe<false>` is not implemented for `HasPadding<AsBytes2, true>`
|
= help: the trait `ShouldBe<true>` is implemented for `HasPadding<AsBytes2, true>`
= help: see issue #48214
= help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
= note: this error originates in the derive macro `AsBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `HasPadding<AsBytes3, true>: ShouldBe<false>` is not satisfied
--> tests/ui-nightly/struct.rs:66:10
|
66 | #[derive(AsBytes)]
| ^^^^^^^ the trait `ShouldBe<false>` is not implemented for `HasPadding<AsBytes3, true>`
|
= help: the trait `ShouldBe<true>` is implemented for `HasPadding<AsBytes3, true>`
= help: see issue #48214
= help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
= note: this error originates in the derive macro `AsBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0587]: type has conflicting packed and align representation hints
--> tests/ui-nightly/struct.rs:91:1
|
91 | struct Unaligned3;
| ^^^^^^^^^^^^^^^^^

View file

@ -0,0 +1,73 @@
// 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.
#[macro_use]
extern crate zerocopy;
#[path = "../util.rs"]
mod util;
use self::util::AU16;
use std::mem::ManuallyDrop;
fn main() {}
//
// AsBytes errors
//
#[derive(AsBytes)]
#[repr(C)]
union AsBytes1<T> {
foo: ManuallyDrop<T>,
}
#[derive(AsBytes)]
#[repr(C)]
union AsBytes2 {
foo: u8,
bar: [u8; 2],
}
//
// Unaligned errors
//
#[derive(Unaligned)]
#[repr(C, align(2))]
union Unaligned1 {
foo: i16,
bar: AU16,
}
// Transparent unions are unstable; see issue #60405
// <https://github.com/rust-lang/rust/issues/60405> for more information.
// #[derive(Unaligned)]
// #[repr(transparent, align(2))]
// union Unaligned2 {
// foo: u8,
// }
#[derive(Unaligned)]
#[repr(packed, align(2))]
union Unaligned3 {
foo: u8,
}
#[derive(Unaligned)]
#[repr(align(1), align(2))]
struct Unaligned4 {
foo: u8,
}
#[derive(Unaligned)]
#[repr(align(2), align(4))]
struct Unaligned5 {
foo: u8,
}

View file

@ -0,0 +1,48 @@
error: unsupported on types with type parameters
--> tests/ui-nightly/union.rs:24:10
|
24 | #[derive(AsBytes)]
| ^^^^^^^
|
= note: this error originates in the derive macro `AsBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error: cannot derive Unaligned with repr(align(N > 1))
--> tests/ui-nightly/union.rs:42:11
|
42 | #[repr(C, align(2))]
| ^^^^^^^^
error: cannot derive Unaligned with repr(align(N > 1))
--> tests/ui-nightly/union.rs:58:16
|
58 | #[repr(packed, align(2))]
| ^^^^^^^^
error: cannot derive Unaligned with repr(align(N > 1))
--> tests/ui-nightly/union.rs:64:18
|
64 | #[repr(align(1), align(2))]
| ^^^^^^^^
error: cannot derive Unaligned with repr(align(N > 1))
--> tests/ui-nightly/union.rs:70:8
|
70 | #[repr(align(2), align(4))]
| ^^^^^^^^
error[E0277]: the trait bound `HasPadding<AsBytes2, true>: ShouldBe<false>` is not satisfied
--> tests/ui-nightly/union.rs:30:10
|
30 | #[derive(AsBytes)]
| ^^^^^^^ the trait `ShouldBe<false>` is not implemented for `HasPadding<AsBytes2, true>`
|
= help: the trait `ShouldBe<true>` is implemented for `HasPadding<AsBytes2, true>`
= help: see issue #48214
= help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
= note: this error originates in the derive macro `AsBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0587]: type has conflicting packed and align representation hints
--> tests/ui-nightly/union.rs:59:1
|
59 | union Unaligned3 {
| ^^^^^^^^^^^^^^^^

View file

@ -0,0 +1,40 @@
// 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.
extern crate zerocopy;
#[path = "../util.rs"]
mod util;
use core::marker::PhantomData;
use {
static_assertions::assert_impl_all,
zerocopy::{AsBytes, FromBytes, FromZeroes, Unaligned},
};
use self::util::NotZerocopy;
fn main() {}
// Test generic transparent structs
#[derive(AsBytes, FromZeroes, FromBytes, Unaligned)]
#[repr(transparent)]
struct TransparentStruct<T> {
inner: T,
_phantom: PhantomData<()>,
}
// It should be legal to derive these traits on a transparent struct, but it
// must also ensure the traits are only implemented when the inner type
// implements them.
assert_impl_all!(TransparentStruct<NotZerocopy>: FromZeroes);
assert_impl_all!(TransparentStruct<NotZerocopy>: FromBytes);
assert_impl_all!(TransparentStruct<NotZerocopy>: AsBytes);
assert_impl_all!(TransparentStruct<NotZerocopy>: Unaligned);

View file

@ -0,0 +1,111 @@
error[E0277]: the trait bound `NotZerocopy: FromZeroes` is not satisfied
--> tests/ui-stable/derive_transparent.rs:37:18
|
37 | assert_impl_all!(TransparentStruct<NotZerocopy>: FromZeroes);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `FromZeroes` is not implemented for `NotZerocopy`
|
= help: the following other types implement trait `FromZeroes`:
bool
char
isize
i8
i16
i32
i64
i128
and $N others
note: required for `TransparentStruct<NotZerocopy>` to implement `FromZeroes`
--> tests/ui-stable/derive_transparent.rs:27:19
|
27 | #[derive(AsBytes, FromZeroes, FromBytes, Unaligned)]
| ^^^^^^^^^^ unsatisfied trait bound introduced in this `derive` macro
note: required by a bound in `_::{closure#0}::assert_impl_all`
--> tests/ui-stable/derive_transparent.rs:37:1
|
37 | assert_impl_all!(TransparentStruct<NotZerocopy>: FromZeroes);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `assert_impl_all`
= note: this error originates in the derive macro `FromZeroes` which comes from the expansion of the macro `assert_impl_all` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `NotZerocopy: FromBytes` is not satisfied
--> tests/ui-stable/derive_transparent.rs:38:18
|
38 | assert_impl_all!(TransparentStruct<NotZerocopy>: FromBytes);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `FromBytes` is not implemented for `NotZerocopy`
|
= help: the following other types implement trait `FromBytes`:
isize
i8
i16
i32
i64
i128
usize
u8
and $N others
note: required for `TransparentStruct<NotZerocopy>` to implement `FromBytes`
--> tests/ui-stable/derive_transparent.rs:27:31
|
27 | #[derive(AsBytes, FromZeroes, FromBytes, Unaligned)]
| ^^^^^^^^^ unsatisfied trait bound introduced in this `derive` macro
note: required by a bound in `_::{closure#0}::assert_impl_all`
--> tests/ui-stable/derive_transparent.rs:38:1
|
38 | assert_impl_all!(TransparentStruct<NotZerocopy>: FromBytes);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `assert_impl_all`
= note: this error originates in the derive macro `FromBytes` which comes from the expansion of the macro `assert_impl_all` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `NotZerocopy: AsBytes` is not satisfied
--> tests/ui-stable/derive_transparent.rs:39:18
|
39 | assert_impl_all!(TransparentStruct<NotZerocopy>: AsBytes);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `AsBytes` is not implemented for `NotZerocopy`
|
= help: the following other types implement trait `AsBytes`:
bool
char
isize
i8
i16
i32
i64
i128
and $N others
note: required for `TransparentStruct<NotZerocopy>` to implement `AsBytes`
--> tests/ui-stable/derive_transparent.rs:27:10
|
27 | #[derive(AsBytes, FromZeroes, FromBytes, Unaligned)]
| ^^^^^^^ unsatisfied trait bound introduced in this `derive` macro
note: required by a bound in `_::{closure#0}::assert_impl_all`
--> tests/ui-stable/derive_transparent.rs:39:1
|
39 | assert_impl_all!(TransparentStruct<NotZerocopy>: AsBytes);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `assert_impl_all`
= note: this error originates in the derive macro `AsBytes` which comes from the expansion of the macro `assert_impl_all` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `NotZerocopy: Unaligned` is not satisfied
--> tests/ui-stable/derive_transparent.rs:40:18
|
40 | assert_impl_all!(TransparentStruct<NotZerocopy>: Unaligned);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Unaligned` is not implemented for `NotZerocopy`
|
= help: the following other types implement trait `Unaligned`:
bool
i8
u8
TransparentStruct<T>
U16<O>
U32<O>
U64<O>
U128<O>
and $N others
note: required for `TransparentStruct<NotZerocopy>` to implement `Unaligned`
--> tests/ui-stable/derive_transparent.rs:27:42
|
27 | #[derive(AsBytes, FromZeroes, FromBytes, Unaligned)]
| ^^^^^^^^^ unsatisfied trait bound introduced in this `derive` macro
note: required by a bound in `_::{closure#0}::assert_impl_all`
--> tests/ui-stable/derive_transparent.rs:40:1
|
40 | assert_impl_all!(TransparentStruct<NotZerocopy>: Unaligned);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `assert_impl_all`
= note: this error originates in the derive macro `Unaligned` which comes from the expansion of the macro `assert_impl_all` (in Nightly builds, run with -Z macro-backtrace for more info)

View file

@ -0,0 +1,194 @@
// 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.
#[macro_use]
extern crate zerocopy;
fn main() {}
//
// Generic errors
//
#[derive(FromZeroes, FromBytes)]
#[repr("foo")]
enum Generic1 {
A,
}
#[derive(FromZeroes, FromBytes)]
#[repr(foo)]
enum Generic2 {
A,
}
#[derive(FromZeroes, FromBytes)]
#[repr(transparent)]
enum Generic3 {
A,
}
#[derive(FromZeroes, FromBytes)]
#[repr(u8, u16)]
enum Generic4 {
A,
}
#[derive(FromZeroes, FromBytes)]
enum Generic5 {
A,
}
//
// FromZeroes errors
//
#[derive(FromZeroes)]
enum FromZeroes1 {
A(u8),
}
#[derive(FromZeroes)]
enum FromZeroes2 {
A,
B(u8),
}
#[derive(FromZeroes)]
enum FromZeroes3 {
A = 1,
B,
}
//
// FromBytes errors
//
#[derive(FromZeroes, FromBytes)]
#[repr(C)]
enum FromBytes1 {
A,
}
#[derive(FromZeroes, FromBytes)]
#[repr(usize)]
enum FromBytes2 {
A,
}
#[derive(FromZeroes, FromBytes)]
#[repr(isize)]
enum FromBytes3 {
A,
}
#[derive(FromZeroes, FromBytes)]
#[repr(u32)]
enum FromBytes4 {
A,
}
#[derive(FromZeroes, FromBytes)]
#[repr(i32)]
enum FromBytes5 {
A,
}
#[derive(FromZeroes, FromBytes)]
#[repr(u64)]
enum FromBytes6 {
A,
}
#[derive(FromZeroes, FromBytes)]
#[repr(i64)]
enum FromBytes7 {
A,
}
//
// Unaligned errors
//
#[derive(Unaligned)]
#[repr(C)]
enum Unaligned1 {
A,
}
#[derive(Unaligned)]
#[repr(u16)]
enum Unaligned2 {
A,
}
#[derive(Unaligned)]
#[repr(i16)]
enum Unaligned3 {
A,
}
#[derive(Unaligned)]
#[repr(u32)]
enum Unaligned4 {
A,
}
#[derive(Unaligned)]
#[repr(i32)]
enum Unaligned5 {
A,
}
#[derive(Unaligned)]
#[repr(u64)]
enum Unaligned6 {
A,
}
#[derive(Unaligned)]
#[repr(i64)]
enum Unaligned7 {
A,
}
#[derive(Unaligned)]
#[repr(usize)]
enum Unaligned8 {
A,
}
#[derive(Unaligned)]
#[repr(isize)]
enum Unaligned9 {
A,
}
#[derive(Unaligned)]
#[repr(u8, align(2))]
enum Unaligned10 {
A,
}
#[derive(Unaligned)]
#[repr(i8, align(2))]
enum Unaligned11 {
A,
}
#[derive(Unaligned)]
#[repr(align(1), align(2))]
enum Unaligned12 {
A,
}
#[derive(Unaligned)]
#[repr(align(2), align(4))]
enum Unaligned13 {
A,
}

View file

@ -0,0 +1,201 @@
error: unrecognized representation hint
--> tests/ui-stable/enum.rs:19:8
|
19 | #[repr("foo")]
| ^^^^^
error: unrecognized representation hint
--> tests/ui-stable/enum.rs:25:8
|
25 | #[repr(foo)]
| ^^^
error: unsupported representation for deriving FromBytes, AsBytes, or Unaligned on an enum
--> tests/ui-stable/enum.rs:31:8
|
31 | #[repr(transparent)]
| ^^^^^^^^^^^
error: conflicting representation hints
--> tests/ui-stable/enum.rs:37:1
|
37 | #[repr(u8, u16)]
| ^
error: must have a non-align #[repr(...)] attribute in order to guarantee this type's memory layout
--> tests/ui-stable/enum.rs:42:22
|
42 | #[derive(FromZeroes, FromBytes)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `FromBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error: only C-like enums can implement FromZeroes
--> tests/ui-stable/enum.rs:52:1
|
52 | / enum FromZeroes1 {
53 | | A(u8),
54 | | }
| |_^
error: only C-like enums can implement FromZeroes
--> tests/ui-stable/enum.rs:57:1
|
57 | / enum FromZeroes2 {
58 | | A,
59 | | B(u8),
60 | | }
| |_^
error: FromZeroes only supported on enums with a variant that has a discriminant of `0`
--> tests/ui-stable/enum.rs:63:1
|
63 | / enum FromZeroes3 {
64 | | A = 1,
65 | | B,
66 | | }
| |_^
error: FromBytes requires repr of "u8", "u16", "i8", or "i16"
--> tests/ui-stable/enum.rs:73:8
|
73 | #[repr(C)]
| ^
error: FromBytes requires repr of "u8", "u16", "i8", or "i16"
--> tests/ui-stable/enum.rs:79:8
|
79 | #[repr(usize)]
| ^^^^^
error: FromBytes requires repr of "u8", "u16", "i8", or "i16"
--> tests/ui-stable/enum.rs:85:8
|
85 | #[repr(isize)]
| ^^^^^
error: FromBytes requires repr of "u8", "u16", "i8", or "i16"
--> tests/ui-stable/enum.rs:91:8
|
91 | #[repr(u32)]
| ^^^
error: FromBytes requires repr of "u8", "u16", "i8", or "i16"
--> tests/ui-stable/enum.rs:97:8
|
97 | #[repr(i32)]
| ^^^
error: FromBytes requires repr of "u8", "u16", "i8", or "i16"
--> tests/ui-stable/enum.rs:103:8
|
103 | #[repr(u64)]
| ^^^
error: FromBytes requires repr of "u8", "u16", "i8", or "i16"
--> tests/ui-stable/enum.rs:109:8
|
109 | #[repr(i64)]
| ^^^
error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1)))
--> tests/ui-stable/enum.rs:119:8
|
119 | #[repr(C)]
| ^
error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1)))
--> tests/ui-stable/enum.rs:125:8
|
125 | #[repr(u16)]
| ^^^
error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1)))
--> tests/ui-stable/enum.rs:131:8
|
131 | #[repr(i16)]
| ^^^
error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1)))
--> tests/ui-stable/enum.rs:137:8
|
137 | #[repr(u32)]
| ^^^
error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1)))
--> tests/ui-stable/enum.rs:143:8
|
143 | #[repr(i32)]
| ^^^
error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1)))
--> tests/ui-stable/enum.rs:149:8
|
149 | #[repr(u64)]
| ^^^
error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1)))
--> tests/ui-stable/enum.rs:155:8
|
155 | #[repr(i64)]
| ^^^
error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1)))
--> tests/ui-stable/enum.rs:161:8
|
161 | #[repr(usize)]
| ^^^^^
error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1)))
--> tests/ui-stable/enum.rs:167:8
|
167 | #[repr(isize)]
| ^^^^^
error: cannot derive Unaligned with repr(align(N > 1))
--> tests/ui-stable/enum.rs:173:12
|
173 | #[repr(u8, align(2))]
| ^^^^^^^^
error: cannot derive Unaligned with repr(align(N > 1))
--> tests/ui-stable/enum.rs:179:12
|
179 | #[repr(i8, align(2))]
| ^^^^^^^^
error: cannot derive Unaligned with repr(align(N > 1))
--> tests/ui-stable/enum.rs:185:18
|
185 | #[repr(align(1), align(2))]
| ^^^^^^^^
error: cannot derive Unaligned with repr(align(N > 1))
--> tests/ui-stable/enum.rs:191:8
|
191 | #[repr(align(2), align(4))]
| ^^^^^^^^
error[E0565]: meta item in `repr` must be an identifier
--> tests/ui-stable/enum.rs:19:8
|
19 | #[repr("foo")]
| ^^^^^
error[E0552]: unrecognized representation hint
--> tests/ui-stable/enum.rs:25:8
|
25 | #[repr(foo)]
| ^^^
|
= help: valid reprs are `Rust` (default), `C`, `align`, `packed`, `transparent`, `simd`, `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize`
error[E0566]: conflicting representation hints
--> tests/ui-stable/enum.rs:37:8
|
37 | #[repr(u8, u16)]
| ^^ ^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #68585 <https://github.com/rust-lang/rust/issues/68585>
= note: `#[deny(conflicting_repr_hints)]` on by default

View file

@ -0,0 +1,272 @@
// 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.
#[macro_use]
extern crate zerocopy;
fn main() {}
#[derive(FromBytes)]
#[repr(u8)]
enum Foo {
Variant0,
Variant1,
Variant2,
Variant3,
Variant4,
Variant5,
Variant6,
Variant7,
Variant8,
Variant9,
Variant10,
Variant11,
Variant12,
Variant13,
Variant14,
Variant15,
Variant16,
Variant17,
Variant18,
Variant19,
Variant20,
Variant21,
Variant22,
Variant23,
Variant24,
Variant25,
Variant26,
Variant27,
Variant28,
Variant29,
Variant30,
Variant31,
Variant32,
Variant33,
Variant34,
Variant35,
Variant36,
Variant37,
Variant38,
Variant39,
Variant40,
Variant41,
Variant42,
Variant43,
Variant44,
Variant45,
Variant46,
Variant47,
Variant48,
Variant49,
Variant50,
Variant51,
Variant52,
Variant53,
Variant54,
Variant55,
Variant56,
Variant57,
Variant58,
Variant59,
Variant60,
Variant61,
Variant62,
Variant63,
Variant64,
Variant65,
Variant66,
Variant67,
Variant68,
Variant69,
Variant70,
Variant71,
Variant72,
Variant73,
Variant74,
Variant75,
Variant76,
Variant77,
Variant78,
Variant79,
Variant80,
Variant81,
Variant82,
Variant83,
Variant84,
Variant85,
Variant86,
Variant87,
Variant88,
Variant89,
Variant90,
Variant91,
Variant92,
Variant93,
Variant94,
Variant95,
Variant96,
Variant97,
Variant98,
Variant99,
Variant100,
Variant101,
Variant102,
Variant103,
Variant104,
Variant105,
Variant106,
Variant107,
Variant108,
Variant109,
Variant110,
Variant111,
Variant112,
Variant113,
Variant114,
Variant115,
Variant116,
Variant117,
Variant118,
Variant119,
Variant120,
Variant121,
Variant122,
Variant123,
Variant124,
Variant125,
Variant126,
Variant127,
Variant128,
Variant129,
Variant130,
Variant131,
Variant132,
Variant133,
Variant134,
Variant135,
Variant136,
Variant137,
Variant138,
Variant139,
Variant140,
Variant141,
Variant142,
Variant143,
Variant144,
Variant145,
Variant146,
Variant147,
Variant148,
Variant149,
Variant150,
Variant151,
Variant152,
Variant153,
Variant154,
Variant155,
Variant156,
Variant157,
Variant158,
Variant159,
Variant160,
Variant161,
Variant162,
Variant163,
Variant164,
Variant165,
Variant166,
Variant167,
Variant168,
Variant169,
Variant170,
Variant171,
Variant172,
Variant173,
Variant174,
Variant175,
Variant176,
Variant177,
Variant178,
Variant179,
Variant180,
Variant181,
Variant182,
Variant183,
Variant184,
Variant185,
Variant186,
Variant187,
Variant188,
Variant189,
Variant190,
Variant191,
Variant192,
Variant193,
Variant194,
Variant195,
Variant196,
Variant197,
Variant198,
Variant199,
Variant200,
Variant201,
Variant202,
Variant203,
Variant204,
Variant205,
Variant206,
Variant207,
Variant208,
Variant209,
Variant210,
Variant211,
Variant212,
Variant213,
Variant214,
Variant215,
Variant216,
Variant217,
Variant218,
Variant219,
Variant220,
Variant221,
Variant222,
Variant223,
Variant224,
Variant225,
Variant226,
Variant227,
Variant228,
Variant229,
Variant230,
Variant231,
Variant232,
Variant233,
Variant234,
Variant235,
Variant236,
Variant237,
Variant238,
Variant239,
Variant240,
Variant241,
Variant242,
Variant243,
Variant244,
Variant245,
Variant246,
Variant247,
Variant248,
Variant249,
Variant250,
Variant251,
Variant252,
Variant253,
Variant254,
}

View file

@ -0,0 +1,11 @@
error: FromBytes only supported on repr(u8) enum with 256 variants
--> tests/ui-stable/enum_from_bytes_u8_too_few.rs:15:1
|
15 | / #[repr(u8)]
16 | | enum Foo {
17 | | Variant0,
18 | | Variant1,
... |
271 | | Variant254,
272 | | }
| |_^

View file

@ -0,0 +1,75 @@
// 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.
#[macro_use]
extern crate zerocopy;
#[path = "../util.rs"]
mod util;
use self::util::{NotZerocopy, AU16};
use zerocopy::KnownLayout;
fn main() {}
// These tests cause errors which are generated by a later compilation pass than
// the other errors we generate, and so if they're compiled in the same file,
// the compiler will never get to that pass, and so we won't get the errors.
//
// FromZeroes errors
//
#[derive(FromZeroes)]
struct FromZeroes1 {
value: NotZerocopy,
}
//
// FromBytes errors
//
#[derive(FromBytes)]
struct FromBytes1 {
value: NotZerocopy,
}
//
// AsBytes errors
//
#[derive(AsBytes)]
#[repr(C)]
struct AsBytes1 {
value: NotZerocopy,
}
//
// Unaligned errors
//
#[derive(Unaligned)]
#[repr(C)]
struct Unaligned1 {
aligned: AU16,
}
// This specifically tests a bug we had in an old version of the code in which
// the trait bound would only be enforced for the first field's type.
#[derive(Unaligned)]
#[repr(C)]
struct Unaligned2 {
unaligned: u8,
aligned: AU16,
}
#[derive(Unaligned)]
#[repr(transparent)]
struct Unaligned3 {
aligned: AU16,
}

View file

@ -0,0 +1,144 @@
warning: unused import: `zerocopy::KnownLayout`
--> tests/ui-stable/late_compile_pass.rs:16:5
|
16 | use zerocopy::KnownLayout;
| ^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(unused_imports)]` on by default
error[E0277]: the trait bound `NotZerocopy: FromZeroes` is not satisfied
--> tests/ui-stable/late_compile_pass.rs:28:10
|
28 | #[derive(FromZeroes)]
| ^^^^^^^^^^ the trait `FromZeroes` is not implemented for `NotZerocopy`
|
= help: the following other types implement trait `FromZeroes`:
bool
char
isize
i8
i16
i32
i64
i128
and $N others
= help: see issue #48214
= note: this error originates in the derive macro `FromZeroes` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `NotZerocopy: FromBytes` is not satisfied
--> tests/ui-stable/late_compile_pass.rs:37:10
|
37 | #[derive(FromBytes)]
| ^^^^^^^^^ the trait `FromBytes` is not implemented for `NotZerocopy`
|
= help: the following other types implement trait `FromBytes`:
isize
i8
i16
i32
i64
i128
usize
u8
and $N others
= help: see issue #48214
= note: this error originates in the derive macro `FromBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `FromBytes1: FromZeroes` is not satisfied
--> tests/ui-stable/late_compile_pass.rs:37:10
|
37 | #[derive(FromBytes)]
| ^^^^^^^^^ the trait `FromZeroes` is not implemented for `FromBytes1`
|
= help: the following other types implement trait `FromZeroes`:
bool
char
isize
i8
i16
i32
i64
i128
and $N others
note: required by a bound in `FromBytes`
--> $WORKSPACE/src/lib.rs
|
| pub unsafe trait FromBytes: FromZeroes {
| ^^^^^^^^^^ required by this bound in `FromBytes`
= note: this error originates in the derive macro `FromBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `NotZerocopy: AsBytes` is not satisfied
--> tests/ui-stable/late_compile_pass.rs:46:10
|
46 | #[derive(AsBytes)]
| ^^^^^^^ the trait `AsBytes` is not implemented for `NotZerocopy`
|
= help: the following other types implement trait `AsBytes`:
bool
char
isize
i8
i16
i32
i64
i128
and $N others
= help: see issue #48214
= note: this error originates in the derive macro `AsBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `AU16: Unaligned` is not satisfied
--> tests/ui-stable/late_compile_pass.rs:56:10
|
56 | #[derive(Unaligned)]
| ^^^^^^^^^ the trait `Unaligned` is not implemented for `AU16`
|
= help: the following other types implement trait `Unaligned`:
bool
i8
u8
Unaligned1
Unaligned2
Unaligned3
U16<O>
U32<O>
and $N others
= help: see issue #48214
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `AU16: Unaligned` is not satisfied
--> tests/ui-stable/late_compile_pass.rs:64:10
|
64 | #[derive(Unaligned)]
| ^^^^^^^^^ the trait `Unaligned` is not implemented for `AU16`
|
= help: the following other types implement trait `Unaligned`:
bool
i8
u8
Unaligned1
Unaligned2
Unaligned3
U16<O>
U32<O>
and $N others
= help: see issue #48214
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `AU16: Unaligned` is not satisfied
--> tests/ui-stable/late_compile_pass.rs:71:10
|
71 | #[derive(Unaligned)]
| ^^^^^^^^^ the trait `Unaligned` is not implemented for `AU16`
|
= help: the following other types implement trait `Unaligned`:
bool
i8
u8
Unaligned1
Unaligned2
Unaligned3
U16<O>
U32<O>
and $N others
= help: see issue #48214
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)

View file

@ -0,0 +1,61 @@
// Copyright 2023 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.
extern crate zerocopy;
use zerocopy::KnownLayout;
fn main() {}
// These tests cause errors which are generated by a later compilation pass than
// the other errors we generate, and so if they're compiled in the same file,
// the compiler will never get to that pass, and so we won't get the errors.
//
// KnownLayout errors
//
fn assert_kl<T: ?Sized + KnownLayout>(_: &T) {}
// | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
// | N | Y | N | N | KL04 |
#[derive(KnownLayout)]
struct KL04<T: ?Sized>(u8, T);
fn test_kl04<T: ?Sized>(kl: &KL04<T>) {
assert_kl(kl);
}
// | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
// | N | Y | Y | N | KL06 |
#[derive(KnownLayout)]
struct KL06<T: ?Sized + KnownLayout>(u8, T);
fn test_kl06<T: ?Sized + KnownLayout>(kl: &KL06<T>) {
assert_kl(kl);
}
// | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
// | Y | Y | N | N | KL12 |
#[derive(KnownLayout)]
#[repr(C)]
struct KL12<T: ?Sized>(u8, T);
fn test_kl12<T: ?Sized>(kl: &KL12<T>) {
assert_kl(kl)
}
// | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
// | Y | Y | N | Y | KL13 |
#[derive(KnownLayout)]
#[repr(C)]
struct KL13<T>(u8, T);
fn test_kl13<T>(t: T) -> impl KnownLayout {
KL13(0u8, t)
}

View file

@ -0,0 +1,104 @@
error[E0277]: the trait bound `T: KnownLayout` is not satisfied
--> tests/ui-stable/mid_compile_pass.rs:59:26
|
59 | fn test_kl13<T>(t: T) -> impl KnownLayout {
| ^^^^^^^^^^^^^^^^ the trait `KnownLayout` is not implemented for `T`
|
note: required for `KL13<T>` to implement `KnownLayout`
--> tests/ui-stable/mid_compile_pass.rs:55:10
|
55 | #[derive(KnownLayout)]
| ^^^^^^^^^^^ unsatisfied trait bound introduced in this `derive` macro
= note: this error originates in the derive macro `KnownLayout` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider restricting type parameter `T`
|
59 | fn test_kl13<T: zerocopy::KnownLayout>(t: T) -> impl KnownLayout {
| +++++++++++++++++++++++
error[E0277]: the size for values of type `T` cannot be known at compilation time
--> tests/ui-stable/mid_compile_pass.rs:31:15
|
30 | fn test_kl04<T: ?Sized>(kl: &KL04<T>) {
| - this type parameter needs to be `Sized`
31 | assert_kl(kl);
| --------- ^^ doesn't have a size known at compile-time
| |
| required by a bound introduced by this call
|
note: required because it appears within the type `KL04<T>`
--> tests/ui-stable/mid_compile_pass.rs:28:8
|
28 | struct KL04<T: ?Sized>(u8, T);
| ^^^^
note: required for `KL04<T>` to implement `KnownLayout`
--> tests/ui-stable/mid_compile_pass.rs:27:10
|
27 | #[derive(KnownLayout)]
| ^^^^^^^^^^^ unsatisfied trait bound introduced in this `derive` macro
note: required by a bound in `assert_kl`
--> tests/ui-stable/mid_compile_pass.rs:23:26
|
23 | fn assert_kl<T: ?Sized + KnownLayout>(_: &T) {}
| ^^^^^^^^^^^ required by this bound in `assert_kl`
= note: this error originates in the derive macro `KnownLayout` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider removing the `?Sized` bound to make the type parameter `Sized`
|
30 - fn test_kl04<T: ?Sized>(kl: &KL04<T>) {
30 + fn test_kl04<T>(kl: &KL04<T>) {
|
error[E0277]: the size for values of type `T` cannot be known at compilation time
--> tests/ui-stable/mid_compile_pass.rs:40:15
|
39 | fn test_kl06<T: ?Sized + KnownLayout>(kl: &KL06<T>) {
| - this type parameter needs to be `Sized`
40 | assert_kl(kl);
| --------- ^^ doesn't have a size known at compile-time
| |
| required by a bound introduced by this call
|
note: required because it appears within the type `KL06<T>`
--> tests/ui-stable/mid_compile_pass.rs:37:8
|
37 | struct KL06<T: ?Sized + KnownLayout>(u8, T);
| ^^^^
note: required for `KL06<T>` to implement `KnownLayout`
--> tests/ui-stable/mid_compile_pass.rs:36:10
|
36 | #[derive(KnownLayout)]
| ^^^^^^^^^^^ unsatisfied trait bound introduced in this `derive` macro
note: required by a bound in `assert_kl`
--> tests/ui-stable/mid_compile_pass.rs:23:26
|
23 | fn assert_kl<T: ?Sized + KnownLayout>(_: &T) {}
| ^^^^^^^^^^^ required by this bound in `assert_kl`
= note: this error originates in the derive macro `KnownLayout` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider removing the `?Sized` bound to make the type parameter `Sized`
|
39 - fn test_kl06<T: ?Sized + KnownLayout>(kl: &KL06<T>) {
39 + fn test_kl06<T: KnownLayout>(kl: &KL06<T>) {
|
error[E0277]: the trait bound `T: KnownLayout` is not satisfied
--> tests/ui-stable/mid_compile_pass.rs:50:15
|
50 | assert_kl(kl)
| --------- ^^ the trait `KnownLayout` is not implemented for `T`
| |
| required by a bound introduced by this call
|
note: required for `KL12<T>` to implement `KnownLayout`
--> tests/ui-stable/mid_compile_pass.rs:45:10
|
45 | #[derive(KnownLayout)]
| ^^^^^^^^^^^ unsatisfied trait bound introduced in this `derive` macro
note: required by a bound in `assert_kl`
--> tests/ui-stable/mid_compile_pass.rs:23:26
|
23 | fn assert_kl<T: ?Sized + KnownLayout>(_: &T) {}
| ^^^^^^^^^^^ required by this bound in `assert_kl`
= note: this error originates in the derive macro `KnownLayout` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider further restricting this bound
|
49 | fn test_kl12<T: ?Sized + zerocopy::KnownLayout>(kl: &KL12<T>) {
| +++++++++++++++++++++++

View file

@ -0,0 +1,99 @@
// 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.
#[macro_use]
extern crate zerocopy;
#[path = "../util.rs"]
mod util;
use zerocopy::KnownLayout;
use self::util::AU16;
fn main() {}
//
// KnownLayout errors
//
struct NotKnownLayout;
struct NotKnownLayoutDst([u8]);
// | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
// | N | N | N | N | KL00 |
#[derive(KnownLayout)]
struct KL00(u8, NotKnownLayoutDst);
// | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
// | N | N | Y | N | KL02 |
#[derive(KnownLayout)]
struct KL02(u8, [u8]);
// | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
// | Y | N | N | N | KL08 |
#[derive(KnownLayout)]
#[repr(C)]
struct KL08(u8, NotKnownLayoutDst);
// | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
// | Y | N | N | Y | KL09 |
#[derive(KnownLayout)]
#[repr(C)]
struct KL09(NotKnownLayout, NotKnownLayout);
//
// AsBytes errors
//
#[derive(AsBytes)]
#[repr(C)]
struct AsBytes1<T>(T);
#[derive(AsBytes)]
#[repr(C)]
struct AsBytes2 {
foo: u8,
bar: AU16,
}
#[derive(AsBytes)]
#[repr(C, packed(2))]
struct AsBytes3 {
foo: u8,
// We'd prefer to use AU64 here, but you can't use aligned types in
// packed structs.
bar: u64,
}
//
// Unaligned errors
//
#[derive(Unaligned)]
#[repr(C, align(2))]
struct Unaligned1;
#[derive(Unaligned)]
#[repr(transparent, align(2))]
struct Unaligned2 {
foo: u8,
}
#[derive(Unaligned)]
#[repr(packed, align(2))]
struct Unaligned3;
#[derive(Unaligned)]
#[repr(align(1), align(2))]
struct Unaligned4;
#[derive(Unaligned)]
#[repr(align(2), align(4))]
struct Unaligned5;

View file

@ -0,0 +1,131 @@
error: unsupported on generic structs that are not repr(transparent) or repr(packed)
--> tests/ui-stable/struct.rs:55:10
|
55 | #[derive(AsBytes)]
| ^^^^^^^
|
= note: this error originates in the derive macro `AsBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error: cannot derive Unaligned with repr(align(N > 1))
--> tests/ui-stable/struct.rs:80:11
|
80 | #[repr(C, align(2))]
| ^^^^^^^^
error: cannot derive Unaligned with repr(align(N > 1))
--> tests/ui-stable/struct.rs:84:21
|
84 | #[repr(transparent, align(2))]
| ^^^^^^^^
error: cannot derive Unaligned with repr(align(N > 1))
--> tests/ui-stable/struct.rs:90:16
|
90 | #[repr(packed, align(2))]
| ^^^^^^^^
error: cannot derive Unaligned with repr(align(N > 1))
--> tests/ui-stable/struct.rs:94:18
|
94 | #[repr(align(1), align(2))]
| ^^^^^^^^
error: cannot derive Unaligned with repr(align(N > 1))
--> tests/ui-stable/struct.rs:98:8
|
98 | #[repr(align(2), align(4))]
| ^^^^^^^^
error[E0692]: transparent struct cannot have other repr hints
--> tests/ui-stable/struct.rs:84:8
|
84 | #[repr(transparent, align(2))]
| ^^^^^^^^^^^ ^^^^^^^^
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
--> tests/ui-stable/struct.rs:31:10
|
31 | #[derive(KnownLayout)]
| ^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: within `KL00`, the trait `Sized` is not implemented for `[u8]`
note: required because it appears within the type `KL00`
--> tests/ui-stable/struct.rs:32:8
|
32 | struct KL00(u8, NotKnownLayoutDst);
| ^^^^
= help: see issue #48214
= note: this error originates in the derive macro `KnownLayout` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
--> tests/ui-stable/struct.rs:36:10
|
36 | #[derive(KnownLayout)]
| ^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: within `KL02`, the trait `Sized` is not implemented for `[u8]`
note: required because it appears within the type `KL02`
--> tests/ui-stable/struct.rs:37:8
|
37 | struct KL02(u8, [u8]);
| ^^^^
= help: see issue #48214
= note: this error originates in the derive macro `KnownLayout` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `NotKnownLayoutDst: KnownLayout` is not satisfied
--> tests/ui-stable/struct.rs:41:10
|
41 | #[derive(KnownLayout)]
| ^^^^^^^^^^^ the trait `KnownLayout` is not implemented for `NotKnownLayoutDst`
|
= help: the following other types implement trait `KnownLayout`:
bool
char
isize
i8
i16
i32
i64
i128
and $N others
= help: see issue #48214
= note: this error originates in the derive macro `KnownLayout` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `NotKnownLayout: KnownLayout` is not satisfied
--> tests/ui-stable/struct.rs:47:10
|
47 | #[derive(KnownLayout)]
| ^^^^^^^^^^^ the trait `KnownLayout` is not implemented for `NotKnownLayout`
|
= help: the following other types implement trait `KnownLayout`:
bool
char
isize
i8
i16
i32
i64
i128
and $N others
= help: see issue #48214
= note: this error originates in the derive macro `KnownLayout` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `HasPadding<AsBytes2, true>: ShouldBe<false>` is not satisfied
--> tests/ui-stable/struct.rs:59:10
|
59 | #[derive(AsBytes)]
| ^^^^^^^ the trait `ShouldBe<false>` is not implemented for `HasPadding<AsBytes2, true>`
|
= help: the trait `ShouldBe<VALUE>` is implemented for `HasPadding<T, VALUE>`
= help: see issue #48214
= note: this error originates in the derive macro `AsBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `HasPadding<AsBytes3, true>: ShouldBe<false>` is not satisfied
--> tests/ui-stable/struct.rs:66:10
|
66 | #[derive(AsBytes)]
| ^^^^^^^ the trait `ShouldBe<false>` is not implemented for `HasPadding<AsBytes3, true>`
|
= help: the trait `ShouldBe<VALUE>` is implemented for `HasPadding<T, VALUE>`
= help: see issue #48214
= note: this error originates in the derive macro `AsBytes` (in Nightly builds, run with -Z macro-backtrace for more info)

View file

@ -0,0 +1,73 @@
// 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.
#[macro_use]
extern crate zerocopy;
#[path = "../util.rs"]
mod util;
use self::util::AU16;
use std::mem::ManuallyDrop;
fn main() {}
//
// AsBytes errors
//
#[derive(AsBytes)]
#[repr(C)]
union AsBytes1<T> {
foo: ManuallyDrop<T>,
}
#[derive(AsBytes)]
#[repr(C)]
union AsBytes2 {
foo: u8,
bar: [u8; 2],
}
//
// Unaligned errors
//
#[derive(Unaligned)]
#[repr(C, align(2))]
union Unaligned1 {
foo: i16,
bar: AU16,
}
// Transparent unions are unstable; see issue #60405
// <https://github.com/rust-lang/rust/issues/60405> for more information.
// #[derive(Unaligned)]
// #[repr(transparent, align(2))]
// union Unaligned2 {
// foo: u8,
// }
#[derive(Unaligned)]
#[repr(packed, align(2))]
union Unaligned3 {
foo: u8,
}
#[derive(Unaligned)]
#[repr(align(1), align(2))]
struct Unaligned4 {
foo: u8,
}
#[derive(Unaligned)]
#[repr(align(2), align(4))]
struct Unaligned5 {
foo: u8,
}

View file

@ -0,0 +1,41 @@
error: unsupported on types with type parameters
--> tests/ui-stable/union.rs:24:10
|
24 | #[derive(AsBytes)]
| ^^^^^^^
|
= note: this error originates in the derive macro `AsBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error: cannot derive Unaligned with repr(align(N > 1))
--> tests/ui-stable/union.rs:42:11
|
42 | #[repr(C, align(2))]
| ^^^^^^^^
error: cannot derive Unaligned with repr(align(N > 1))
--> tests/ui-stable/union.rs:58:16
|
58 | #[repr(packed, align(2))]
| ^^^^^^^^
error: cannot derive Unaligned with repr(align(N > 1))
--> tests/ui-stable/union.rs:64:18
|
64 | #[repr(align(1), align(2))]
| ^^^^^^^^
error: cannot derive Unaligned with repr(align(N > 1))
--> tests/ui-stable/union.rs:70:8
|
70 | #[repr(align(2), align(4))]
| ^^^^^^^^
error[E0277]: the trait bound `HasPadding<AsBytes2, true>: ShouldBe<false>` is not satisfied
--> tests/ui-stable/union.rs:30:10
|
30 | #[derive(AsBytes)]
| ^^^^^^^ the trait `ShouldBe<false>` is not implemented for `HasPadding<AsBytes2, true>`
|
= help: the trait `ShouldBe<VALUE>` is implemented for `HasPadding<T, VALUE>`
= help: see issue #48214
= note: this error originates in the derive macro `AsBytes` (in Nightly builds, run with -Z macro-backtrace for more info)

View file

@ -0,0 +1,75 @@
// 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.
#![allow(warnings)]
use std::{marker::PhantomData, option::IntoIter};
use {static_assertions::assert_impl_all, zerocopy::AsBytes};
// A union is `AsBytes` if:
// - all fields are `AsBytes`
// - `repr(C)` or `repr(transparent)` and
// - no padding (size of union equals size of each field type)
// - `repr(packed)`
#[derive(AsBytes, Clone, Copy)]
#[repr(C)]
union CZst {
a: (),
}
assert_impl_all!(CZst: AsBytes);
#[derive(AsBytes)]
#[repr(C)]
union C {
a: u8,
b: u8,
}
assert_impl_all!(C: AsBytes);
// Transparent unions are unstable; see issue #60405
// <https://github.com/rust-lang/rust/issues/60405> for more information.
// #[derive(AsBytes)]
// #[repr(transparent)]
// union Transparent {
// a: u8,
// b: CZst,
// }
// is_as_bytes!(Transparent);
#[derive(AsBytes)]
#[repr(C, packed)]
union CZstPacked {
a: (),
}
assert_impl_all!(CZstPacked: AsBytes);
#[derive(AsBytes)]
#[repr(C, packed)]
union CPacked {
a: u8,
b: i8,
}
assert_impl_all!(CPacked: AsBytes);
#[derive(AsBytes)]
#[repr(C, packed)]
union CMultibytePacked {
a: i32,
b: u32,
c: f32,
}
assert_impl_all!(CMultibytePacked: AsBytes);

View file

@ -0,0 +1,72 @@
// 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.
#![allow(warnings)]
use std::{marker::PhantomData, option::IntoIter};
use {
static_assertions::assert_impl_all,
zerocopy::{FromBytes, FromZeroes},
};
// A union is `FromBytes` if:
// - all fields are `FromBytes`
#[derive(Clone, Copy, FromZeroes, FromBytes)]
union Zst {
a: (),
}
assert_impl_all!(Zst: FromBytes);
#[derive(FromZeroes, FromBytes)]
union One {
a: u8,
}
assert_impl_all!(One: FromBytes);
#[derive(FromZeroes, FromBytes)]
union Two {
a: u8,
b: Zst,
}
assert_impl_all!(Two: FromBytes);
#[derive(FromZeroes, FromBytes)]
union TypeParams<'a, T: Copy, I: Iterator>
where
I::Item: Copy,
{
a: T,
c: I::Item,
d: u8,
e: PhantomData<&'a [u8]>,
f: PhantomData<&'static str>,
g: PhantomData<String>,
}
assert_impl_all!(TypeParams<'static, (), IntoIter<()>>: FromBytes);
// Deriving `FromBytes` should work if the union has bounded parameters.
#[derive(FromZeroes, FromBytes)]
#[repr(C)]
union WithParams<'a: 'b, 'b: 'a, const N: usize, T: 'a + 'b + FromBytes>
where
'a: 'b,
'b: 'a,
T: 'a + 'b + Copy + FromBytes,
{
a: [T; N],
b: PhantomData<&'a &'b ()>,
}
assert_impl_all!(WithParams<'static, 'static, 42, u8>: FromBytes);

View file

@ -0,0 +1,72 @@
// 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.
#![allow(warnings)]
#[macro_use]
mod util;
use std::{marker::PhantomData, option::IntoIter};
use {static_assertions::assert_impl_all, zerocopy::FromZeroes};
// A union is `FromZeroes` if:
// - all fields are `FromZeroes`
#[derive(Clone, Copy, FromZeroes)]
union Zst {
a: (),
}
assert_impl_all!(Zst: FromZeroes);
#[derive(FromZeroes)]
union One {
a: bool,
}
assert_impl_all!(One: FromZeroes);
#[derive(FromZeroes)]
union Two {
a: bool,
b: Zst,
}
assert_impl_all!(Two: FromZeroes);
#[derive(FromZeroes)]
union TypeParams<'a, T: Copy, I: Iterator>
where
I::Item: Copy,
{
a: T,
c: I::Item,
d: u8,
e: PhantomData<&'a [u8]>,
f: PhantomData<&'static str>,
g: PhantomData<String>,
}
assert_impl_all!(TypeParams<'static, (), IntoIter<()>>: FromZeroes);
// Deriving `FromZeroes` should work if the union has bounded parameters.
#[derive(FromZeroes)]
#[repr(C)]
union WithParams<'a: 'b, 'b: 'a, const N: usize, T: 'a + 'b + FromZeroes>
where
'a: 'b,
'b: 'a,
T: 'a + 'b + Copy + FromZeroes,
{
a: [T; N],
b: PhantomData<&'a &'b ()>,
}
assert_impl_all!(WithParams<'static, 'static, 42, u8>: FromZeroes);

View file

@ -0,0 +1,65 @@
// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#![allow(warnings)]
#[macro_use]
mod util;
use std::{marker::PhantomData, option::IntoIter};
use {static_assertions::assert_impl_all, zerocopy::KnownLayout};
#[derive(Clone, Copy, KnownLayout)]
union Zst {
a: (),
}
assert_impl_all!(Zst: KnownLayout);
#[derive(KnownLayout)]
union One {
a: bool,
}
assert_impl_all!(One: KnownLayout);
#[derive(KnownLayout)]
union Two {
a: bool,
b: Zst,
}
assert_impl_all!(Two: KnownLayout);
#[derive(KnownLayout)]
union TypeParams<'a, T: Copy, I: Iterator>
where
I::Item: Copy,
{
a: T,
c: I::Item,
d: u8,
e: PhantomData<&'a [u8]>,
f: PhantomData<&'static str>,
g: PhantomData<String>,
}
assert_impl_all!(TypeParams<'static, (), IntoIter<()>>: KnownLayout);
// Deriving `KnownLayout` should work if the union has bounded parameters.
#[derive(KnownLayout)]
#[repr(C)]
union WithParams<'a: 'b, 'b: 'a, const N: usize, T: 'a + 'b + KnownLayout>
where
'a: 'b,
'b: 'a,
T: 'a + 'b + Copy + KnownLayout,
{
a: [T; N],
b: PhantomData<&'a &'b ()>,
}
assert_impl_all!(WithParams<'static, 'static, 42, u8>: KnownLayout);

View file

@ -0,0 +1,77 @@
// 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.
#![allow(warnings)]
use std::{marker::PhantomData, option::IntoIter};
use {static_assertions::assert_impl_all, zerocopy::Unaligned};
// A union is `Unaligned` if:
// - `repr(align)` is no more than 1 and either
// - `repr(C)` or `repr(transparent)` and
// - all fields `Unaligned`
// - `repr(packed)`
#[derive(Unaligned)]
#[repr(C)]
union Foo {
a: u8,
}
assert_impl_all!(Foo: Unaligned);
// Transparent unions are unstable; see issue #60405
// <https://github.com/rust-lang/rust/issues/60405> for more information.
// #[derive(Unaligned)]
// #[repr(transparent)]
// union Bar {
// a: u8,
// }
// is_unaligned!(Bar);
#[derive(Unaligned)]
#[repr(packed)]
union Baz {
// NOTE: The `u16` type is not guaranteed to have alignment 2, although it
// does on many platforms. However, to fix this would require a custom type
// with a `#[repr(align(2))]` attribute, and `#[repr(packed)]` types are not
// allowed to transitively contain `#[repr(align(...))]` types. Thus, we
// have no choice but to use `u16` here. Luckily, these tests run in CI on
// platforms on which `u16` has alignment 2, so this isn't that big of a
// deal.
a: u16,
}
assert_impl_all!(Baz: Unaligned);
#[derive(Unaligned)]
#[repr(C, align(1))]
union FooAlign {
a: u8,
}
assert_impl_all!(FooAlign: Unaligned);
#[derive(Unaligned)]
#[repr(C)]
union TypeParams<'a, T: Copy, I: Iterator>
where
I::Item: Copy,
{
a: T,
c: I::Item,
d: u8,
e: PhantomData<&'a [u8]>,
f: PhantomData<&'static str>,
g: PhantomData<String>,
}
assert_impl_all!(TypeParams<'static, (), IntoIter<()>>: Unaligned);

View file

@ -0,0 +1,20 @@
// 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.
use zerocopy::{AsBytes, FromBytes, FromZeroes, KnownLayout};
/// A type that doesn't implement any zerocopy traits.
pub struct NotZerocopy<T = ()>(T);
/// A `u16` with alignment 2.
///
/// Though `u16` has alignment 2 on some platforms, it's not guaranteed. By
/// contrast, `AU16` is guaranteed to have alignment 2.
#[derive(KnownLayout, FromZeroes, FromBytes, AsBytes, Copy, Clone)]
#[repr(C, align(2))]
pub struct AU16(u16);