summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrederick Mayle <fmayle@google.com>2023-09-28 16:20:43 -0700
committerFrederick Mayle <fmayle@google.com>2023-10-12 14:23:48 -0700
commit65b2dfba54d6aad522cb1e68473ac73606c34a6e (patch)
tree5ee455d88a857f173887c1d54e2543929fff7b81
parented92e3395a5662c8cc764adb42be000e8799ccf4 (diff)
downloadzerocopy-derive-65b2dfba54d6aad522cb1e68473ac73606c34a6e.tar.gz
Upgrade zerocopy-derive to 0.7.5
This project was upgraded with external_updater. Usage: tools/external_updater/updater.sh update rust/crates/zerocopy-derive For more info, check https://cs.android.com/android/platform/superproject/+/main:tools/external_updater/README.md Bug: 302709631 Test: TreeHugger Change-Id: I9b1109b3083cc6cac812be9c2c4f4ba5c22d7749
-rw-r--r--.cargo_vcs_info.json2
-rw-r--r--Android.bp4
-rw-r--r--Cargo.toml15
-rw-r--r--Cargo.toml.orig50
-rw-r--r--METADATA14
-rw-r--r--src/ext.rs51
-rw-r--r--src/lib.rs373
-rw-r--r--src/repr.rs4
-rw-r--r--tests/enum_as_bytes.rs35
-rw-r--r--tests/enum_from_bytes.rs42
-rw-r--r--tests/enum_from_zeroes.rs31
-rw-r--r--tests/enum_unaligned.rs21
-rw-r--r--tests/hygiene.rs17
-rw-r--r--tests/paths_and_modules.rs13
-rw-r--r--tests/priv_in_pub.rs20
-rw-r--r--tests/struct_as_bytes.rs98
-rw-r--r--tests/struct_from_bytes.rs57
-rw-r--r--tests/struct_from_zeroes.rs58
-rw-r--r--tests/struct_unaligned.rs56
-rw-r--r--tests/trybuild.rs20
-rw-r--r--tests/ui-msrv/derive_transparent.rs36
-rw-r--r--tests/ui-msrv/derive_transparent.stderr71
-rw-r--r--tests/ui-msrv/enum.rs45
-rw-r--r--tests/ui-msrv/enum.stderr120
-rw-r--r--tests/ui-msrv/late_compile_pass.rs25
-rw-r--r--tests/ui-msrv/late_compile_pass.stderr90
-rw-r--r--tests/ui-msrv/struct.rs12
-rw-r--r--tests/ui-msrv/struct.stderr43
-rw-r--r--tests/ui-msrv/union.rs8
-rw-r--r--tests/ui-msrv/union.stderr44
-rw-r--r--tests/ui-nightly/derive_transparent.rs36
-rw-r--r--tests/ui-nightly/derive_transparent.stderr111
-rw-r--r--tests/ui-nightly/enum.rs (renamed from tests/ui/enum.rs)45
-rw-r--r--tests/ui-nightly/enum.stderr (renamed from tests/ui/enum.stderr)136
-rw-r--r--tests/ui-nightly/enum_from_bytes_u16_too_few.rs.disabled (renamed from tests/ui/enum_from_bytes_u16_too_few.rs.disabled)0
-rw-r--r--tests/ui-nightly/enum_from_bytes_u8_too_few.rs (renamed from tests/ui/enum_from_bytes_u8_too_few.rs)0
-rw-r--r--tests/ui-nightly/enum_from_bytes_u8_too_few.stderr (renamed from tests/ui/enum_from_bytes_u8_too_few.stderr)2
-rw-r--r--tests/ui-nightly/late_compile_pass.rs (renamed from tests/ui/late_compile_pass.rs)25
-rw-r--r--tests/ui-nightly/late_compile_pass.stderr142
-rw-r--r--tests/ui-nightly/struct.rs (renamed from tests/ui/struct.rs)12
-rw-r--r--tests/ui-nightly/struct.stderr54
-rw-r--r--tests/ui-nightly/union.rs (renamed from tests/ui/union.rs)8
-rw-r--r--tests/ui-nightly/union.stderr42
-rw-r--r--tests/ui-stable/derive_transparent.rs36
-rw-r--r--tests/ui-stable/derive_transparent.stderr111
-rw-r--r--tests/ui-stable/enum.rs45
-rw-r--r--tests/ui-stable/enum.stderr124
-rw-r--r--tests/ui-stable/late_compile_pass.rs25
-rw-r--r--tests/ui-stable/late_compile_pass.stderr160
-rw-r--r--tests/ui-stable/struct.rs12
-rw-r--r--tests/ui-stable/struct.stderr42
-rw-r--r--tests/ui-stable/union.rs8
-rw-r--r--tests/ui-stable/union.stderr42
-rw-r--r--tests/ui/late_compile_pass.stderr84
-rw-r--r--tests/ui/struct.stderr49
-rw-r--r--tests/ui/union.stderr51
-rw-r--r--tests/union_as_bytes.rs23
-rw-r--r--tests/union_from_bytes.rs32
-rw-r--r--tests/union_from_zeroes.rs52
-rw-r--r--tests/union_unaligned.rs28
-rw-r--r--tests/util.rs16
61 files changed, 1974 insertions, 1054 deletions
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index 99908cd..0273786 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,6 +1,6 @@
{
"git": {
- "sha1": "8efbd0038df30e39cba9f6df6cb4577571dcc3d8"
+ "sha1": "c150d4f1b75fc21240574b6b7dbbcdc236d388b0"
},
"path_in_vcs": "zerocopy-derive"
} \ No newline at end of file
diff --git a/Android.bp b/Android.bp
index 85b6bb7..25f2bb2 100644
--- a/Android.bp
+++ b/Android.bp
@@ -24,9 +24,9 @@ rust_proc_macro {
name: "libzerocopy_derive",
crate_name: "zerocopy_derive",
cargo_env_compat: true,
- cargo_pkg_version: "0.3.2",
+ cargo_pkg_version: "0.7.5",
srcs: ["src/lib.rs"],
- edition: "2018",
+ edition: "2021",
rustlibs: [
"libproc_macro2",
"libquote",
diff --git a/Cargo.toml b/Cargo.toml
index b00e3c3..1909eaa 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -10,13 +10,14 @@
# See Cargo.toml.orig for the original contents.
[package]
-edition = "2018"
+edition = "2021"
+rust-version = "1.61.0"
name = "zerocopy-derive"
-version = "0.3.2"
+version = "0.7.5"
authors = ["Joshua Liebow-Feeser <joshlf@google.com>"]
exclude = [".*"]
description = "Custom derive for traits from the zerocopy crate"
-license-file = "LICENSE"
+license = "BSD-2-Clause"
repository = "https://github.com/google/zerocopy"
[lib]
@@ -29,11 +30,13 @@ version = "1.0.1"
version = "1.0.10"
[dependencies.syn]
-version = "2"
-features = ["visit"]
+version = "2.0.31"
[dev-dependencies.rustversion]
version = "1.0"
+[dev-dependencies.static_assertions]
+version = "1.1"
+
[dev-dependencies.trybuild]
-version = "1.0"
+version = "=1.0.80"
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index 1f7ec41..4cb0f08 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -1,39 +1,33 @@
-# 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.
+# Copyright 2019 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.
[package]
-edition = "2018"
+edition = "2021"
name = "zerocopy-derive"
-version = "0.3.2"
+version = "0.7.5"
authors = ["Joshua Liebow-Feeser <joshlf@google.com>"]
-exclude = [".*"]
description = "Custom derive for traits from the zerocopy crate"
-license-file = "LICENSE"
+license = "BSD-2-Clause"
repository = "https://github.com/google/zerocopy"
+rust-version = "1.61.0"
+
+exclude = [".*"]
[lib]
proc-macro = true
-[dependencies.proc-macro2]
-version = "1.0.1"
-
-[dependencies.quote]
-version = "1.0.10"
-
-[dependencies.syn]
-version = "1.0.5"
-features = ["visit"]
-
-[dev-dependencies.rustversion]
-version = "1.0"
+[dependencies]
+proc-macro2 = "1.0.1"
+quote = "1.0.10"
+syn = "2.0.31"
-[dev-dependencies.trybuild]
-version = "1.0"
+[dev-dependencies]
+rustversion = "1.0"
+static_assertions = "1.1"
+# Pinned to a specific version so that the version used for local development
+# and the version used in CI are guaranteed to be the same. Future versions
+# sometimes change the output format slightly, so a version mismatch can cause
+# CI test failures.
+trybuild = "=1.0.80"
+zerocopy = { path = "../", features = ["default", "derive"] }
diff --git a/METADATA b/METADATA
index 58f90fb..33d1126 100644
--- a/METADATA
+++ b/METADATA
@@ -1,3 +1,7 @@
+# This project was upgraded with external_updater.
+# Usage: tools/external_updater/updater.sh update rust/crates/zerocopy-derive
+# For more info, check https://cs.android.com/android/platform/superproject/+/main:tools/external_updater/README.md
+
name: "zerocopy-derive"
description: "Custom derive for traits from the zerocopy crate"
third_party {
@@ -7,13 +11,13 @@ third_party {
}
url {
type: ARCHIVE
- value: "https://static.crates.io/crates/zerocopy-derive/zerocopy-derive-0.3.2.crate"
+ value: "https://static.crates.io/crates/zerocopy-derive/zerocopy-derive-0.7.5.crate"
}
- version: "0.3.2"
+ version: "0.7.5"
license_type: NOTICE
last_upgrade_date {
- year: 2022
- month: 11
- day: 18
+ year: 2023
+ month: 9
+ day: 28
}
}
diff --git a/src/ext.rs b/src/ext.rs
index 45b592e..ff8a3d6 100644
--- a/src/ext.rs
+++ b/src/ext.rs
@@ -2,34 +2,39 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-use syn::{Data, DataEnum, DataStruct, DataUnion, Field, Fields, Type};
+use syn::{Data, DataEnum, DataStruct, DataUnion, Type};
pub trait DataExt {
- fn nested_types(&self) -> Vec<&Type>;
+ /// 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 nested_types(&self) -> Vec<&Type> {
+ fn field_types(&self) -> Vec<&Type> {
match self {
- Data::Struct(strc) => strc.nested_types(),
- Data::Enum(enm) => enm.nested_types(),
- Data::Union(un) => un.nested_types(),
+ Data::Struct(strc) => strc.field_types(),
+ Data::Enum(enm) => enm.field_types(),
+ Data::Union(un) => un.field_types(),
}
}
}
impl DataExt for DataStruct {
- fn nested_types(&self) -> Vec<&Type> {
- fields_to_types(&self.fields)
+ fn field_types(&self) -> Vec<&Type> {
+ self.fields.iter().map(|f| &f.ty).collect()
}
}
impl DataExt for DataEnum {
- fn nested_types(&self) -> Vec<&Type> {
- self.variants.iter().map(|var| fields_to_types(&var.fields)).fold(Vec::new(), |mut a, b| {
- a.extend(b);
- a
- })
+ 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()
}
}
@@ -39,24 +44,6 @@ pub trait EnumExt {
impl EnumExt for DataEnum {
fn is_c_like(&self) -> bool {
- self.nested_types().is_empty()
+ self.field_types().is_empty()
}
}
-
-impl DataExt for DataUnion {
- fn nested_types(&self) -> Vec<&Type> {
- field_iter_to_types(&self.fields.named)
- }
-}
-
-fn fields_to_types(fields: &Fields) -> Vec<&Type> {
- match fields {
- Fields::Named(named) => field_iter_to_types(&named.named),
- Fields::Unnamed(unnamed) => field_iter_to_types(&unnamed.unnamed),
- Fields::Unit => Vec::new(),
- }
-}
-
-fn field_iter_to_types<'a, I: IntoIterator<Item = &'a Field>>(fields: I) -> Vec<&'a Type> {
- fields.into_iter().map(|f| &f.ty).collect()
-}
diff --git a/src/lib.rs b/src/lib.rs
index f6f51c2..6b9e3a4 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -2,6 +2,26 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+//! 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;
@@ -10,10 +30,9 @@ mod repr;
use {
proc_macro2::Span,
quote::quote,
- syn::visit::{self, Visit},
syn::{
- parse_quote, punctuated::Punctuated, token::Comma, Data, DataEnum, DataStruct, DataUnion,
- DeriveInput, Error, GenericParam, Ident, Lifetime, Type, TypePath,
+ parse_quote, Data, DataEnum, DataStruct, DataUnion, DeriveInput, Error, Expr, ExprLit,
+ GenericParam, Ident, Lit,
},
};
@@ -30,12 +49,23 @@ use {crate::ext::*, crate::repr::*};
// help: required by the derive of FromBytes
//
// Instead, we have more verbose error messages like "unsupported representation
-// for deriving FromBytes, AsBytes, or Unaligned on an enum"
+// 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(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);
@@ -87,11 +117,59 @@ const STRUCT_UNION_ALLOWED_REPR_COMBINATIONS: &[&[StructRepr]] = &[
&[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, "FromZeroes", true, 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, "FromZeroes", true, 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, "FromZeroes", true, 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, "FromBytes", true, PaddingCheck::None)
+ impl_block(ast, strct, "FromBytes", true, None)
}
// An enum is `FromBytes` if:
@@ -134,7 +212,7 @@ fn derive_from_bytes_enum(ast: &DeriveInput, enm: &DataEnum) -> proc_macro2::Tok
.to_compile_error();
}
- impl_block(ast, enm, "FromBytes", true, PaddingCheck::None)
+ impl_block(ast, enm, "FromBytes", true, None)
}
#[rustfmt::skip]
@@ -165,7 +243,7 @@ const ENUM_FROM_BYTES_CFG: Config<EnumRepr> = {
// - all fields are `FromBytes`
fn derive_from_bytes_union(ast: &DeriveInput, unn: &DataUnion) -> proc_macro2::TokenStream {
- impl_block(ast, unn, "FromBytes", true, PaddingCheck::None)
+ impl_block(ast, unn, "FromBytes", true, None)
}
// A struct is `AsBytes` if:
@@ -175,16 +253,30 @@ fn derive_from_bytes_union(ast: &DeriveInput, unn: &DataUnion) -> proc_macro2::T
// - `repr(packed)`
fn derive_as_bytes_struct(ast: &DeriveInput, strct: &DataStruct) -> 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();
- }
-
let reprs = try_or_print!(STRUCT_UNION_AS_BYTES_CFG.validate_reprs(ast));
- let padding_check =
- if reprs.contains(&StructRepr::Packed) { PaddingCheck::None } else { PaddingCheck::Struct };
+ 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, "AsBytes", true, padding_check)
}
@@ -208,7 +300,7 @@ fn derive_as_bytes_enum(ast: &DeriveInput, enm: &DataEnum) -> proc_macro2::Token
// 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, "AsBytes", false, PaddingCheck::None)
+ impl_block(ast, enm, "AsBytes", false, None)
}
#[rustfmt::skip]
@@ -250,7 +342,7 @@ fn derive_as_bytes_union(ast: &DeriveInput, unn: &DataUnion) -> proc_macro2::Tok
try_or_print!(STRUCT_UNION_AS_BYTES_CFG.validate_reprs(ast));
- impl_block(ast, unn, "AsBytes", true, PaddingCheck::Union)
+ impl_block(ast, unn, "AsBytes", true, Some(PaddingCheck::Union))
}
// A struct is `Unaligned` if:
@@ -263,7 +355,7 @@ fn derive_unaligned_struct(ast: &DeriveInput, strct: &DataStruct) -> proc_macro2
let reprs = try_or_print!(STRUCT_UNION_UNALIGNED_CFG.validate_reprs(ast));
let require_trait_bound = !reprs.contains(&StructRepr::Packed);
- impl_block(ast, strct, "Unaligned", require_trait_bound, PaddingCheck::None)
+ impl_block(ast, strct, "Unaligned", require_trait_bound, None)
}
const STRUCT_UNION_UNALIGNED_CFG: Config<StructRepr> = Config {
@@ -294,7 +386,7 @@ fn derive_unaligned_enum(ast: &DeriveInput, enm: &DataEnum) -> proc_macro2::Toke
// for `require_trait_bounds` 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, "Unaligned", true, PaddingCheck::None)
+ impl_block(ast, enm, "Unaligned", true, None)
}
#[rustfmt::skip]
@@ -332,26 +424,37 @@ fn derive_unaligned_union(ast: &DeriveInput, unn: &DataUnion) -> proc_macro2::To
let reprs = try_or_print!(STRUCT_UNION_UNALIGNED_CFG.validate_reprs(ast));
let require_trait_bound = !reprs.contains(&StructRepr::Packed);
- impl_block(ast, unn, "Unaligned", require_trait_bound, PaddingCheck::None)
+ impl_block(ast, unn, "Unaligned", require_trait_bound, None)
}
// This enum describes what kind of padding check needs to be generated for the
// associated impl.
enum PaddingCheck {
- // No additional padding check is required.
- None,
// 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())
+ }
+}
+
fn impl_block<D: DataExt>(
input: &DeriveInput,
data: &D,
trait_name: &str,
require_trait_bound: bool,
- padding_check: PaddingCheck,
+ padding_check: Option<PaddingCheck>,
) -> proc_macro2::TokenStream {
// In this documentation, we will refer to this hypothetical struct:
//
@@ -367,22 +470,10 @@ fn impl_block<D: DataExt>(
// c: I::Item,
// }
//
- // First, we extract the field types, which in this case are `u8`, `T`, and
- // `I::Item`. We use the names of the type parameters to split the field
- // types into two sets - a set of types which are based on the type
- // parameters, and a set of types which are not. First, we re-use the
- // existing parameters and where clauses, generating an `impl` block like:
- //
- // impl<T, I: Iterator> FromBytes for Foo<T, I>
- // where
- // T: Copy,
- // I: Clone,
- // I::Item: Clone,
- // {
- // }
- //
- // Then, we use the list of types which are based on the type parameters to
- // generate new entries in the `where` clause:
+ // 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
@@ -394,18 +485,6 @@ fn impl_block<D: DataExt>(
// {
// }
//
- // Finally, we use a different technique to generate the bounds for the
- // types which are not based on type parameters:
- //
- //
- // fn only_derive_is_allowed_to_implement_this_trait() where Self: Sized {
- // struct ImplementsFromBytes<F: ?Sized + FromBytes>(PhantomData<F>);
- // let _: ImplementsFromBytes<u8>;
- // }
- //
- // It would be easier to put all types in the where clause, but that won't
- // work until the trivial_bounds feature is stabilized (#48214).
- //
// 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
@@ -416,31 +495,9 @@ fn impl_block<D: DataExt>(
// `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
- // some pretty serious downsides that are worth calling out:
- //
- // 1. You lose the ability to have fields of generic type with reduced visibility.
- //
- // #[derive(Unaligned)]
- // #[repr(C)]
- // pub struct Public<T>(Private<T>);
- //
- // #[derive(Unaligned)]
- // #[repr(C)]
- // struct Private<T>(T);
- //
- //
- // warning: private type `Private<T>` in public interface (error E0446)
- // --> src/main.rs:6:10
- // |
- // 6 | #[derive(Unaligned)]
- // | ^^^^^^^^^
- // |
- // = note: #[warn(private_in_public)] 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 #34537 <https://github.com/rust-lang/rust/issues/34537>
- //
- // 2. When lifetimes are involved, the trait solver ties itself in knots.
+ // 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)]
@@ -449,7 +506,6 @@ fn impl_block<D: DataExt>(
// b: PhantomData<&'b u8>,
// }
//
- //
// error[E0283]: type annotations required: cannot resolve `core::marker::PhantomData<&'a u8>: zerocopy::Unaligned`
// --> src/main.rs:6:10
// |
@@ -458,67 +514,37 @@ fn impl_block<D: DataExt>(
// |
// = note: required by `zerocopy::Unaligned`
- // A visitor which is used to walk a field's type and determine whether any
- // of its definition is based on the type or lifetime parameters on a type.
- struct FromTypeParamVisit<'a, 'b>(&'a Punctuated<GenericParam, Comma>, &'b mut bool);
-
- impl<'a, 'b> Visit<'a> for FromTypeParamVisit<'a, 'b> {
- fn visit_lifetime(&mut self, i: &'a Lifetime) {
- visit::visit_lifetime(self, i);
- if self.0.iter().any(|param| {
- if let GenericParam::Lifetime(param) = param {
- param.lifetime.ident == i.ident
- } else {
- false
- }
- }) {
- *self.1 = true;
- }
- }
-
- fn visit_type_path(&mut self, i: &'a TypePath) {
- visit::visit_type_path(self, i);
- if self.0.iter().any(|param| {
- if let GenericParam::Type(param) = param {
- i.path.segments.first().unwrap().ident == param.ident
- } else {
- false
- }
- }) {
- *self.1 = true;
- }
- }
- }
-
- // Whether this type is based on one of the type parameters. E.g., given the
- // type parameters `<T>`, `T`, `T::Foo`, and `(T::Foo, String)` are all
- // based on the type parameters, while `String` and `(String, Box<()>)` are
- // not.
- let is_from_type_param = |ty: &Type| {
- let mut ret = false;
- FromTypeParamVisit(&input.generics.params, &mut ret).visit_type(ty);
- ret
- };
-
+ let type_ident = &input.ident;
let trait_ident = Ident::new(trait_name, Span::call_site());
+ let field_types = data.field_types();
+
+ let field_type_bounds = require_trait_bound
+ .then(|| field_types.iter().map(|ty| parse_quote!(#ty: zerocopy::#trait_ident)))
+ .into_iter()
+ .flatten()
+ .collect::<Vec<_>>();
+
+ // 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::derive_util::HasPadding<#type_ident, {zerocopy::#validator_macro!(#type_ident, #(#fields),*)}>:
+ zerocopy::derive_util::ShouldBe<false>
+ )
+ });
- let field_types = data.nested_types();
- let type_param_field_types = field_types.iter().filter(|ty| is_from_type_param(ty));
- let non_type_param_field_types = field_types.iter().filter(|ty| !is_from_type_param(ty));
-
- // Add a new set of where clause predicates of the form `T: Trait` for each
- // of the types of the struct's fields (but only the ones whose types are
- // based on one of the type parameters).
- let mut generics = input.generics.clone();
- let where_clause = generics.make_where_clause();
- if require_trait_bound {
- for ty in type_param_field_types {
- let bound = parse_quote!(#ty: zerocopy::#trait_ident);
- where_clause.predicates.push(bound);
- }
- }
+ 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());
- let type_ident = &input.ident;
// The parameters with trait bounds, but without type defaults.
let params = input.generics.params.clone().into_iter().map(|mut param| {
match &mut param {
@@ -538,56 +564,12 @@ fn impl_block<D: DataExt>(
GenericParam::Const(cnst) => quote!(#cnst),
});
- let trait_bound_body = if require_trait_bound {
- let implements_type_ident =
- Ident::new(format!("Implements{}", trait_ident).as_str(), Span::call_site());
- let implements_type_tokens = quote!(#implements_type_ident);
- let types = non_type_param_field_types.map(|ty| quote!(#implements_type_tokens<#ty>));
- quote!(
- // A type with a type parameter that must implement `#trait_ident`.
- struct #implements_type_ident<F: ?Sized + zerocopy::#trait_ident>(::core::marker::PhantomData<F>);
- // For each field type, an instantiation that won't type check if
- // that type doesn't implement `#trait_ident`.
- #(let _: #types;)*
- )
- } else {
- quote!()
- };
-
- let size_check_body = match (field_types.is_empty(), padding_check) {
- (true, _) | (false, PaddingCheck::None) => quote!(),
- (false, PaddingCheck::Struct) => quote!(
- const _: () = {
- trait HasPadding<const HAS_PADDING: bool> {}
- fn assert_no_padding<T: HasPadding<false>>() {}
-
- const COMPOSITE_TYPE_SIZE: usize = ::core::mem::size_of::<#type_ident>();
- const SUM_FIELD_SIZES: usize = 0 #(+ ::core::mem::size_of::<#field_types>())*;
- const HAS_PADDING: bool = COMPOSITE_TYPE_SIZE > SUM_FIELD_SIZES;
- impl HasPadding<HAS_PADDING> for #type_ident {}
- let _ = assert_no_padding::<#type_ident>;
- };
- ),
- (false, PaddingCheck::Union) => quote!(
- const _: () = {
- trait FieldsAreSameSize<const FIELDS_ARE_SAME_SIZE: bool> {}
- fn assert_fields_are_same_size<T: FieldsAreSameSize<true>>() {}
-
- const COMPOSITE_TYPE_SIZE: usize = ::core::mem::size_of::<#type_ident>();
- const FIELDS_ARE_SAME_SIZE: bool = true
- #(&& (::core::mem::size_of::<#field_types>() == COMPOSITE_TYPE_SIZE))*;
- impl FieldsAreSameSize<FIELDS_ARE_SAME_SIZE> for #type_ident {}
- let _ = assert_fields_are_same_size::<#type_ident>;
- };
- ),
- };
-
quote! {
- unsafe impl < #(#params),* > zerocopy::#trait_ident for #type_ident < #(#param_idents),* > #where_clause {
- fn only_derive_is_allowed_to_implement_this_trait() where Self: Sized {
- #trait_bound_body
- #size_check_body
- }
+ unsafe impl < #(#params),* > zerocopy::#trait_ident for #type_ident < #(#param_idents),* >
+ where
+ #(#bounds,)*
+ {
+ fn only_derive_is_allowed_to_implement_this_trait() {}
}
}
}
@@ -596,6 +578,23 @@ 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::*;
@@ -616,12 +615,12 @@ mod tests {
}
fn elements_are_sorted_and_deduped<T: Clone + Ord>(lists: &[&[T]]) -> bool {
- lists.iter().all(|list| is_sorted_and_deduped(*list))
+ 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)
+ 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));
diff --git a/src/repr.rs b/src/repr.rs
index 5bd4a8a..5997ad2 100644
--- a/src/repr.rs
+++ b/src/repr.rs
@@ -73,9 +73,7 @@ impl<R: KindRepr> Config<R> {
}
let initial_sp = metas[0].span();
- let err_span = metas.iter().skip(1).fold(Some(initial_sp), |sp_option, meta| {
- sp_option.and_then(|sp| sp.join(meta.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)
diff --git a/tests/enum_as_bytes.rs b/tests/enum_as_bytes.rs
index be5c53d..e1b8efd 100644
--- a/tests/enum_as_bytes.rs
+++ b/tests/enum_as_bytes.rs
@@ -4,18 +4,7 @@
#![allow(warnings)]
-use zerocopy::AsBytes;
-
-struct IsAsBytes<T: AsBytes>(T);
-
-// Fail compilation if `$ty: !AsBytes`.
-macro_rules! is_as_bytes {
- ($ty:ty) => {
- const _: () = {
- let _: IsAsBytes<$ty>;
- };
- };
-}
+use {static_assertions::assert_impl_all, zerocopy::AsBytes};
// An enum is `AsBytes` if if has a defined repr.
@@ -25,7 +14,7 @@ enum C {
A,
}
-is_as_bytes!(C);
+assert_impl_all!(C: AsBytes);
#[derive(AsBytes)]
#[repr(u8)]
@@ -33,7 +22,7 @@ enum U8 {
A,
}
-is_as_bytes!(U8);
+assert_impl_all!(U8: AsBytes);
#[derive(AsBytes)]
#[repr(u16)]
@@ -41,7 +30,7 @@ enum U16 {
A,
}
-is_as_bytes!(U16);
+assert_impl_all!(U16: AsBytes);
#[derive(AsBytes)]
#[repr(u32)]
@@ -49,7 +38,7 @@ enum U32 {
A,
}
-is_as_bytes!(U32);
+assert_impl_all!(U32: AsBytes);
#[derive(AsBytes)]
#[repr(u64)]
@@ -57,7 +46,7 @@ enum U64 {
A,
}
-is_as_bytes!(U64);
+assert_impl_all!(U64: AsBytes);
#[derive(AsBytes)]
#[repr(usize)]
@@ -65,7 +54,7 @@ enum Usize {
A,
}
-is_as_bytes!(Usize);
+assert_impl_all!(Usize: AsBytes);
#[derive(AsBytes)]
#[repr(i8)]
@@ -73,7 +62,7 @@ enum I8 {
A,
}
-is_as_bytes!(I8);
+assert_impl_all!(I8: AsBytes);
#[derive(AsBytes)]
#[repr(i16)]
@@ -81,7 +70,7 @@ enum I16 {
A,
}
-is_as_bytes!(I16);
+assert_impl_all!(I16: AsBytes);
#[derive(AsBytes)]
#[repr(i32)]
@@ -89,7 +78,7 @@ enum I32 {
A,
}
-is_as_bytes!(I32);
+assert_impl_all!(I32: AsBytes);
#[derive(AsBytes)]
#[repr(i64)]
@@ -97,7 +86,7 @@ enum I64 {
A,
}
-is_as_bytes!(I64);
+assert_impl_all!(I64: AsBytes);
#[derive(AsBytes)]
#[repr(isize)]
@@ -105,4 +94,4 @@ enum Isize {
A,
}
-is_as_bytes!(Isize);
+assert_impl_all!(Isize: AsBytes);
diff --git a/tests/enum_from_bytes.rs b/tests/enum_from_bytes.rs
index 671878d..09fe847 100644
--- a/tests/enum_from_bytes.rs
+++ b/tests/enum_from_bytes.rs
@@ -4,7 +4,12 @@
#![allow(warnings)]
-use zerocopy::FromBytes;
+mod util;
+
+use {
+ static_assertions::assert_impl_all,
+ zerocopy::{FromBytes, FromZeroes},
+};
// An enum is `FromBytes` if:
// - `repr(uN)` or `repr(iN)`
@@ -23,18 +28,7 @@ use zerocopy::FromBytes;
// `Variant128` has a discriminant of -128) since Rust won't automatically wrap
// a signed discriminant around without you explicitly telling it to.
-struct IsFromBytes<T: FromBytes>(T);
-
-// Fail compilation if `$ty: !FromBytes`.
-macro_rules! is_from_bytes {
- ($ty:ty) => {
- const _: () = {
- let _: IsFromBytes<$ty>;
- };
- };
-}
-
-#[derive(FromBytes)]
+#[derive(FromZeroes, FromBytes)]
#[repr(u8)]
enum FooU8 {
Variant0,
@@ -295,9 +289,9 @@ enum FooU8 {
Variant255,
}
-is_from_bytes!(FooU8);
+assert_impl_all!(FooU8: FromBytes);
-#[derive(FromBytes)]
+#[derive(FromZeroes, FromBytes)]
#[repr(i8)]
enum FooI8 {
Variant0,
@@ -558,9 +552,9 @@ enum FooI8 {
Variant255,
}
-is_from_bytes!(FooI8);
+assert_impl_all!(FooI8: FromBytes);
-#[derive(FromBytes)]
+#[derive(FromZeroes, FromBytes)]
#[repr(u8, align(2))]
enum FooU8Align {
Variant0,
@@ -821,9 +815,9 @@ enum FooU8Align {
Variant255,
}
-is_from_bytes!(FooU8Align);
+assert_impl_all!(FooU8Align: FromBytes);
-#[derive(FromBytes)]
+#[derive(FromZeroes, FromBytes)]
#[repr(i8, align(2))]
enum FooI8Align {
Variant0,
@@ -1084,9 +1078,9 @@ enum FooI8Align {
Variant255,
}
-is_from_bytes!(FooI8Align);
+assert_impl_all!(FooI8Align: FromBytes);
-#[derive(FromBytes)]
+#[derive(FromZeroes, FromBytes)]
#[repr(u16)]
enum FooU16 {
Variant0,
@@ -66627,9 +66621,9 @@ enum FooU16 {
Variant65535,
}
-is_from_bytes!(FooU16);
+assert_impl_all!(FooU16: FromBytes);
-#[derive(FromBytes)]
+#[derive(FromZeroes, FromBytes)]
#[repr(i16)]
enum FooI16 {
Variant0,
@@ -132170,4 +132164,4 @@ enum FooI16 {
Variant65535,
}
-is_from_bytes!(FooI16);
+assert_impl_all!(FooI16: FromBytes);
diff --git a/tests/enum_from_zeroes.rs b/tests/enum_from_zeroes.rs
new file mode 100644
index 0000000..3fedcb1
--- /dev/null
+++ b/tests/enum_from_zeroes.rs
@@ -0,0 +1,31 @@
+// 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 {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);
diff --git a/tests/enum_unaligned.rs b/tests/enum_unaligned.rs
index 5438135..1c7cb77 100644
--- a/tests/enum_unaligned.rs
+++ b/tests/enum_unaligned.rs
@@ -4,18 +4,7 @@
#![allow(warnings)]
-use zerocopy::Unaligned;
-
-struct IsUnaligned<T: Unaligned>(T);
-
-// Fail compilation if `$ty: !Unaligned`.
-macro_rules! is_unaligned {
- ($ty:ty) => {
- const _: () = {
- let _: IsUnaligned<$ty>;
- };
- };
-}
+use {static_assertions::assert_impl_all, zerocopy::Unaligned};
// An enum is `Unaligned` if:
// - No `repr(align(N > 1))`
@@ -27,7 +16,7 @@ enum Foo {
A,
}
-is_unaligned!(Foo);
+assert_impl_all!(Foo: Unaligned);
#[derive(Unaligned)]
#[repr(i8)]
@@ -35,7 +24,7 @@ enum Bar {
A,
}
-is_unaligned!(Bar);
+assert_impl_all!(Bar: Unaligned);
#[derive(Unaligned)]
#[repr(u8, align(1))]
@@ -43,7 +32,7 @@ enum Baz {
A,
}
-is_unaligned!(Baz);
+assert_impl_all!(Baz: Unaligned);
#[derive(Unaligned)]
#[repr(i8, align(1))]
@@ -51,4 +40,4 @@ enum Blah {
B,
}
-is_unaligned!(Blah);
+assert_impl_all!(Blah: Unaligned);
diff --git a/tests/hygiene.rs b/tests/hygiene.rs
index 42bbae9..9209bcd 100644
--- a/tests/hygiene.rs
+++ b/tests/hygiene.rs
@@ -9,11 +9,18 @@
extern crate zerocopy as _zerocopy;
+#[macro_use]
+mod util;
+
use std::{marker::PhantomData, option::IntoIter};
-use _zerocopy::FromBytes;
+use {
+ _zerocopy::{FromBytes, FromZeroes, Unaligned},
+ static_assertions::assert_impl_all,
+};
-#[derive(FromBytes)]
+#[derive(FromZeroes, FromBytes, Unaligned)]
+#[repr(C)]
struct TypeParams<'a, T, I: Iterator> {
a: T,
c: I::Item,
@@ -23,8 +30,4 @@ struct TypeParams<'a, T, I: Iterator> {
g: PhantomData<String>,
}
-const _FOO: () = {
- let _: IsFromBytes<TypeParams<'static, (), IntoIter<()>>>;
-};
-
-struct IsFromBytes<T: FromBytes>(PhantomData<T>);
+assert_impl_all!(TypeParams<'static, (), IntoIter<()>>: FromZeroes, FromBytes, Unaligned);
diff --git a/tests/paths_and_modules.rs b/tests/paths_and_modules.rs
index 065e8b2..8ca3aa2 100644
--- a/tests/paths_and_modules.rs
+++ b/tests/paths_and_modules.rs
@@ -4,19 +4,21 @@
#![allow(warnings)]
-use zerocopy::FromBytes;
+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::FromBytes;
+ use zerocopy::{AsBytes, FromBytes, FromZeroes, Unaligned};
- #[derive(FromBytes)]
+ #[derive(FromZeroes, FromBytes, AsBytes, Unaligned)]
+ #[repr(C)]
pub struct Foo {
foo: u8,
}
- #[derive(FromBytes)]
+ #[derive(FromZeroes, FromBytes, AsBytes, Unaligned)]
+ #[repr(C)]
pub struct Bar {
bar: u8,
}
@@ -24,7 +26,8 @@ mod foo {
use foo::Foo;
-#[derive(FromBytes)]
+#[derive(FromZeroes, FromBytes, AsBytes, Unaligned)]
+#[repr(C)]
struct Baz {
foo: Foo,
bar: foo::Bar,
diff --git a/tests/priv_in_pub.rs b/tests/priv_in_pub.rs
new file mode 100644
index 0000000..f61568a
--- /dev/null
+++ b/tests/priv_in_pub.rs
@@ -0,0 +1,20 @@
+// Copyright 2019 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.
+
+use zerocopy::{AsBytes, FromBytes, FromZeroes, 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(AsBytes, FromZeroes, FromBytes, Unaligned)]
+#[repr(C)]
+pub struct Public(Private);
+
+#[derive(AsBytes, FromZeroes, FromBytes, Unaligned)]
+#[repr(C)]
+struct Private(());
diff --git a/tests/struct_as_bytes.rs b/tests/struct_as_bytes.rs
index fd464ce..e1507aa 100644
--- a/tests/struct_as_bytes.rs
+++ b/tests/struct_as_bytes.rs
@@ -4,20 +4,13 @@
#![allow(warnings)]
-use std::{marker::PhantomData, option::IntoIter};
+mod util;
-use zerocopy::AsBytes;
+use std::{marker::PhantomData, mem::ManuallyDrop, option::IntoIter};
-struct IsAsBytes<T: AsBytes>(T);
+use {static_assertions::assert_impl_all, zerocopy::AsBytes};
-// Fail compilation if `$ty: !AsBytes`.
-macro_rules! is_as_bytes {
- ($ty:ty) => {
- const _: () = {
- let _: IsAsBytes<$ty>;
- };
- };
-}
+use self::util::AU16;
// A struct is `AsBytes` if:
// - all fields are `AsBytes`
@@ -29,17 +22,17 @@ macro_rules! is_as_bytes {
#[repr(C)]
struct CZst;
-is_as_bytes!(CZst);
+assert_impl_all!(CZst: AsBytes);
#[derive(AsBytes)]
#[repr(C)]
struct C {
a: u8,
b: u8,
- c: u16,
+ c: AU16,
}
-is_as_bytes!(C);
+assert_impl_all!(C: AsBytes);
#[derive(AsBytes)]
#[repr(transparent)]
@@ -48,19 +41,90 @@ struct Transparent {
b: CZst,
}
-is_as_bytes!(Transparent);
+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;
-is_as_bytes!(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)]
+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,
}
-is_as_bytes!(CPacked);
+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);
diff --git a/tests/struct_from_bytes.rs b/tests/struct_from_bytes.rs
index 7ebc300..5dc68d2 100644
--- a/tests/struct_from_bytes.rs
+++ b/tests/struct_from_bytes.rs
@@ -4,52 +4,57 @@
#![allow(warnings)]
-use std::{marker::PhantomData, option::IntoIter};
+mod util;
-use zerocopy::FromBytes;
+use std::{marker::PhantomData, option::IntoIter};
-struct IsFromBytes<T: FromBytes>(T);
+use {
+ static_assertions::assert_impl_all,
+ zerocopy::{FromBytes, FromZeroes},
+};
-// Fail compilation if `$ty: !FromBytes`.
-macro_rules! is_from_bytes {
- ($ty:ty) => {
- const _: () = {
- let _: IsFromBytes<$ty>;
- };
- };
-}
+use crate::util::AU16;
// A struct is `FromBytes` if:
// - all fields are `FromBytes`
-#[derive(FromBytes)]
+#[derive(FromZeroes, FromBytes)]
struct Zst;
-is_from_bytes!(Zst);
+assert_impl_all!(Zst: FromBytes);
-#[derive(FromBytes)]
+#[derive(FromZeroes, FromBytes)]
struct One {
a: u8,
}
-is_from_bytes!(One);
+assert_impl_all!(One: FromBytes);
-#[derive(FromBytes)]
+#[derive(FromZeroes, FromBytes)]
struct Two {
a: u8,
b: Zst,
}
-is_from_bytes!(Two);
+assert_impl_all!(Two: FromBytes);
+
+#[derive(FromZeroes, FromBytes)]
+struct Unsized {
+ a: [u8],
+}
+
+assert_impl_all!(Unsized: FromBytes);
-#[derive(FromBytes)]
-struct TypeParams<'a, T, I: Iterator> {
- a: T,
- c: I::Item,
- d: u8,
- e: PhantomData<&'a [u8]>,
- f: PhantomData<&'static str>,
- g: PhantomData<String>,
+#[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,
}
-is_from_bytes!(TypeParams<'static, (), IntoIter<()>>);
+assert_impl_all!(TypeParams<'static, (), IntoIter<()>>: FromBytes);
+assert_impl_all!(TypeParams<'static, AU16, IntoIter<()>>: FromBytes);
+assert_impl_all!(TypeParams<'static, [AU16], IntoIter<()>>: FromBytes);
diff --git a/tests/struct_from_zeroes.rs b/tests/struct_from_zeroes.rs
new file mode 100644
index 0000000..e9609d1
--- /dev/null
+++ b/tests/struct_from_zeroes.rs
@@ -0,0 +1,58 @@
+// 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::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);
diff --git a/tests/struct_unaligned.rs b/tests/struct_unaligned.rs
index 355c208..e843a0c 100644
--- a/tests/struct_unaligned.rs
+++ b/tests/struct_unaligned.rs
@@ -4,20 +4,13 @@
#![allow(warnings)]
-use std::{marker::PhantomData, option::IntoIter};
+mod util;
-use zerocopy::Unaligned;
+use std::{marker::PhantomData, option::IntoIter};
-struct IsUnaligned<T: Unaligned>(T);
+use {static_assertions::assert_impl_all, zerocopy::Unaligned};
-// Fail compilation if `$ty: !Unaligned`.
-macro_rules! is_unaligned {
- ($ty:ty) => {
- const _: () = {
- let _: IsUnaligned<$ty>;
- };
- };
-}
+use crate::util::AU16;
// A struct is `Unaligned` if:
// - `repr(align)` is no more than 1 and either
@@ -31,7 +24,7 @@ struct Foo {
a: u8,
}
-is_unaligned!(Foo);
+assert_impl_all!(Foo: Unaligned);
#[derive(Unaligned)]
#[repr(transparent)]
@@ -39,15 +32,22 @@ struct Bar {
a: u8,
}
-is_unaligned!(Bar);
+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,
}
-is_unaligned!(Baz);
+assert_impl_all!(Baz: Unaligned);
#[derive(Unaligned)]
#[repr(C, align(1))]
@@ -55,17 +55,27 @@ struct FooAlign {
a: u8,
}
-is_unaligned!(FooAlign);
+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, I: Iterator> {
- a: T,
- c: I::Item,
- d: u8,
- e: PhantomData<&'a [u8]>,
- f: PhantomData<&'static str>,
- g: PhantomData<String>,
+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,
}
-is_unaligned!(TypeParams<'static, (), IntoIter<()>>);
+assert_impl_all!(TypeParams<'static, (), IntoIter<()>>: Unaligned);
+assert_impl_all!(TypeParams<'static, u8, IntoIter<()>>: Unaligned);
+assert_impl_all!(TypeParams<'static, [u8], IntoIter<()>>: Unaligned);
diff --git a/tests/trybuild.rs b/tests/trybuild.rs
index b95a716..32f38cc 100644
--- a/tests/trybuild.rs
+++ b/tests/trybuild.rs
@@ -8,18 +8,18 @@
// pin to specific versions in CI (a specific stable version, a specific date of
// the nightly compiler, and a specific MSRV). Updating those pinned versions
// may also require updating these tests.
-// - `tests/ui` - Contains the source of truth for our UI test source files
-// (`.rs`), and contains `.err` and `.out` files for nightly and beta
-// - `tests/ui-stable` - Contains symlinks to the `.rs` files in `tests/ui`, and
-// contains `.err` and `.out` files for stable
-// - `tests/ui-msrv` - Contains symlinks to the `.rs` files in `tests/ui`, and
-// contains `.err` and `.out` files for MSRV
+// - `tests/ui-nightly` - Contains the source of truth for our UI test source
+// files (`.rs`), and contains `.err` and `.out` files for nightly
+// - `tests/ui-stable` - Contains symlinks to the `.rs` files in
+// `tests/ui-nightly`, and contains `.err` and `.out` files for stable
+// - `tests/ui-msrv` - Contains symlinks to the `.rs` files in
+// `tests/ui-nightly`, and contains `.err` and `.out` files for MSRV
-#[rustversion::any(nightly, beta)]
-const SOURCE_FILES_GLOB: &str = "tests/ui/*.rs";
-#[rustversion::all(stable, not(stable(1.56.1)))]
+#[rustversion::nightly]
+const SOURCE_FILES_GLOB: &str = "tests/ui-nightly/*.rs";
+#[rustversion::stable(1.69.0)]
const SOURCE_FILES_GLOB: &str = "tests/ui-stable/*.rs";
-#[rustversion::stable(1.56.1)]
+#[rustversion::stable(1.61.0)]
const SOURCE_FILES_GLOB: &str = "tests/ui-msrv/*.rs";
#[test]
diff --git a/tests/ui-msrv/derive_transparent.rs b/tests/ui-msrv/derive_transparent.rs
new file mode 100644
index 0000000..a99f92c
--- /dev/null
+++ b/tests/ui-msrv/derive_transparent.rs
@@ -0,0 +1,36 @@
+// Copyright 2019 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.
+
+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);
diff --git a/tests/ui-msrv/derive_transparent.stderr b/tests/ui-msrv/derive_transparent.stderr
new file mode 100644
index 0000000..3218446
--- /dev/null
+++ b/tests/ui-msrv/derive_transparent.stderr
@@ -0,0 +1,71 @@
+error[E0277]: the trait bound `NotZerocopy: FromZeroes` is not satisfied
+ --> tests/ui-msrv/derive_transparent.rs:33:1
+ |
+33 | 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:23:19
+ |
+23 | #[derive(AsBytes, FromZeroes, FromBytes, Unaligned)]
+ | ^^^^^^^^^^
+note: required by a bound in `_::{closure#0}::assert_impl_all`
+ --> tests/ui-msrv/derive_transparent.rs:33:1
+ |
+33 | 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:34:1
+ |
+34 | 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:23:31
+ |
+23 | #[derive(AsBytes, FromZeroes, FromBytes, Unaligned)]
+ | ^^^^^^^^^
+note: required by a bound in `_::{closure#0}::assert_impl_all`
+ --> tests/ui-msrv/derive_transparent.rs:34:1
+ |
+34 | 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:35:1
+ |
+35 | 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:23:10
+ |
+23 | #[derive(AsBytes, FromZeroes, FromBytes, Unaligned)]
+ | ^^^^^^^
+note: required by a bound in `_::{closure#0}::assert_impl_all`
+ --> tests/ui-msrv/derive_transparent.rs:35:1
+ |
+35 | 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:36:1
+ |
+36 | 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:23:42
+ |
+23 | #[derive(AsBytes, FromZeroes, FromBytes, Unaligned)]
+ | ^^^^^^^^^
+note: required by a bound in `_::{closure#0}::assert_impl_all`
+ --> tests/ui-msrv/derive_transparent.rs:36:1
+ |
+36 | 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)
diff --git a/tests/ui-msrv/enum.rs b/tests/ui-msrv/enum.rs
index 188b0a6..c3d1e27 100644
--- a/tests/ui-msrv/enum.rs
+++ b/tests/ui-msrv/enum.rs
@@ -11,76 +11,97 @@ fn main() {}
// Generic errors
//
-#[derive(FromBytes)]
+#[derive(FromZeroes, FromBytes)]
#[repr("foo")]
enum Generic1 {
A,
}
-#[derive(FromBytes)]
+#[derive(FromZeroes, FromBytes)]
#[repr(foo)]
enum Generic2 {
A,
}
-#[derive(FromBytes)]
+#[derive(FromZeroes, FromBytes)]
#[repr(transparent)]
enum Generic3 {
A,
}
-#[derive(FromBytes)]
+#[derive(FromZeroes, FromBytes)]
#[repr(u8, u16)]
enum Generic4 {
A,
}
-#[derive(FromBytes)]
+#[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(FromBytes)]
+#[derive(FromZeroes, FromBytes)]
#[repr(C)]
enum FromBytes1 {
A,
}
-#[derive(FromBytes)]
+#[derive(FromZeroes, FromBytes)]
#[repr(usize)]
enum FromBytes2 {
A,
}
-#[derive(FromBytes)]
+#[derive(FromZeroes, FromBytes)]
#[repr(isize)]
enum FromBytes3 {
A,
}
-#[derive(FromBytes)]
+#[derive(FromZeroes, FromBytes)]
#[repr(u32)]
enum FromBytes4 {
A,
}
-#[derive(FromBytes)]
+#[derive(FromZeroes, FromBytes)]
#[repr(i32)]
enum FromBytes5 {
A,
}
-#[derive(FromBytes)]
+#[derive(FromZeroes, FromBytes)]
#[repr(u64)]
enum FromBytes6 {
A,
}
-#[derive(FromBytes)]
+#[derive(FromZeroes, FromBytes)]
#[repr(i64)]
enum FromBytes7 {
A,
diff --git a/tests/ui-msrv/enum.stderr b/tests/ui-msrv/enum.stderr
index 14ddb0b..a71b072 100644
--- a/tests/ui-msrv/enum.stderr
+++ b/tests/ui-msrv/enum.stderr
@@ -23,131 +23,157 @@ error: conflicting representation hints
| ^
error: must have a non-align #[repr(...)] attribute in order to guarantee this type's memory layout
- --> tests/ui-msrv/enum.rs:38:10
+ --> tests/ui-msrv/enum.rs:38:22
|
-38 | #[derive(FromBytes)]
- | ^^^^^^^^^
+38 | #[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:48:1
+ |
+48 | / enum FromZeroes1 {
+49 | | A(u8),
+50 | | }
+ | |_^
+
+error: only C-like enums can implement FromZeroes
+ --> tests/ui-msrv/enum.rs:53:1
+ |
+53 | / enum FromZeroes2 {
+54 | | A,
+55 | | B(u8),
+56 | | }
+ | |_^
+
+error: FromZeroes only supported on enums with a variant that has a discriminant of `0`
+ --> tests/ui-msrv/enum.rs:59:1
+ |
+59 | / enum FromZeroes3 {
+60 | | A = 1,
+61 | | B,
+62 | | }
+ | |_^
+
error: FromBytes requires repr of "u8", "u16", "i8", or "i16"
- --> tests/ui-msrv/enum.rs:48:8
+ --> tests/ui-msrv/enum.rs:69:8
|
-48 | #[repr(C)]
+69 | #[repr(C)]
| ^
error: FromBytes requires repr of "u8", "u16", "i8", or "i16"
- --> tests/ui-msrv/enum.rs:54:8
+ --> tests/ui-msrv/enum.rs:75:8
|
-54 | #[repr(usize)]
+75 | #[repr(usize)]
| ^^^^^
error: FromBytes requires repr of "u8", "u16", "i8", or "i16"
- --> tests/ui-msrv/enum.rs:60:8
+ --> tests/ui-msrv/enum.rs:81:8
|
-60 | #[repr(isize)]
+81 | #[repr(isize)]
| ^^^^^
error: FromBytes requires repr of "u8", "u16", "i8", or "i16"
- --> tests/ui-msrv/enum.rs:66:8
+ --> tests/ui-msrv/enum.rs:87:8
|
-66 | #[repr(u32)]
+87 | #[repr(u32)]
| ^^^
error: FromBytes requires repr of "u8", "u16", "i8", or "i16"
- --> tests/ui-msrv/enum.rs:72:8
+ --> tests/ui-msrv/enum.rs:93:8
|
-72 | #[repr(i32)]
+93 | #[repr(i32)]
| ^^^
error: FromBytes requires repr of "u8", "u16", "i8", or "i16"
- --> tests/ui-msrv/enum.rs:78:8
+ --> tests/ui-msrv/enum.rs:99:8
|
-78 | #[repr(u64)]
+99 | #[repr(u64)]
| ^^^
error: FromBytes requires repr of "u8", "u16", "i8", or "i16"
- --> tests/ui-msrv/enum.rs:84:8
- |
-84 | #[repr(i64)]
- | ^^^
+ --> tests/ui-msrv/enum.rs:105:8
+ |
+105 | #[repr(i64)]
+ | ^^^
error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1)))
- --> tests/ui-msrv/enum.rs:94:8
- |
-94 | #[repr(C)]
- | ^
+ --> tests/ui-msrv/enum.rs:115:8
+ |
+115 | #[repr(C)]
+ | ^
error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1)))
- --> tests/ui-msrv/enum.rs:100:8
+ --> tests/ui-msrv/enum.rs:121:8
|
-100 | #[repr(u16)]
+121 | #[repr(u16)]
| ^^^
error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1)))
- --> tests/ui-msrv/enum.rs:106:8
+ --> tests/ui-msrv/enum.rs:127:8
|
-106 | #[repr(i16)]
+127 | #[repr(i16)]
| ^^^
error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1)))
- --> tests/ui-msrv/enum.rs:112:8
+ --> tests/ui-msrv/enum.rs:133:8
|
-112 | #[repr(u32)]
+133 | #[repr(u32)]
| ^^^
error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1)))
- --> tests/ui-msrv/enum.rs:118:8
+ --> tests/ui-msrv/enum.rs:139:8
|
-118 | #[repr(i32)]
+139 | #[repr(i32)]
| ^^^
error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1)))
- --> tests/ui-msrv/enum.rs:124:8
+ --> tests/ui-msrv/enum.rs:145:8
|
-124 | #[repr(u64)]
+145 | #[repr(u64)]
| ^^^
error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1)))
- --> tests/ui-msrv/enum.rs:130:8
+ --> tests/ui-msrv/enum.rs:151:8
|
-130 | #[repr(i64)]
+151 | #[repr(i64)]
| ^^^
error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1)))
- --> tests/ui-msrv/enum.rs:136:8
+ --> tests/ui-msrv/enum.rs:157:8
|
-136 | #[repr(usize)]
+157 | #[repr(usize)]
| ^^^^^
error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1)))
- --> tests/ui-msrv/enum.rs:142:8
+ --> tests/ui-msrv/enum.rs:163:8
|
-142 | #[repr(isize)]
+163 | #[repr(isize)]
| ^^^^^
error: cannot derive Unaligned with repr(align(N > 1))
- --> tests/ui-msrv/enum.rs:148:12
+ --> tests/ui-msrv/enum.rs:169:12
|
-148 | #[repr(u8, align(2))]
+169 | #[repr(u8, align(2))]
| ^^^^^^^^
error: cannot derive Unaligned with repr(align(N > 1))
- --> tests/ui-msrv/enum.rs:154:12
+ --> tests/ui-msrv/enum.rs:175:12
|
-154 | #[repr(i8, align(2))]
+175 | #[repr(i8, align(2))]
| ^^^^^^^^
error: cannot derive Unaligned with repr(align(N > 1))
- --> tests/ui-msrv/enum.rs:160:18
+ --> tests/ui-msrv/enum.rs:181:18
|
-160 | #[repr(align(1), align(2))]
+181 | #[repr(align(1), align(2))]
| ^^^^^^^^
error: cannot derive Unaligned with repr(align(N > 1))
- --> tests/ui-msrv/enum.rs:166:8
+ --> tests/ui-msrv/enum.rs:187:8
|
-166 | #[repr(align(2), align(4))]
+187 | #[repr(align(2), align(4))]
| ^^^^^^^^
error[E0565]: meta item in `repr` must be an identifier
diff --git a/tests/ui-msrv/late_compile_pass.rs b/tests/ui-msrv/late_compile_pass.rs
index 3a99c76..1b4c603 100644
--- a/tests/ui-msrv/late_compile_pass.rs
+++ b/tests/ui-msrv/late_compile_pass.rs
@@ -5,6 +5,11 @@
#[macro_use]
extern crate zerocopy;
+#[path = "../util.rs"]
+mod util;
+
+use self::util::{NotZerocopy, AU16};
+
fn main() {}
// These tests cause errors which are generated by a later compilation pass than
@@ -12,12 +17,21 @@ fn main() {}
// 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 {
- not_from_bytes: &'static str,
+ value: NotZerocopy,
}
//
@@ -27,8 +41,7 @@ struct FromBytes1 {
#[derive(AsBytes)]
#[repr(C)]
struct AsBytes1 {
- a: u8,
- b: u16,
+ value: NotZerocopy,
}
//
@@ -38,7 +51,7 @@ struct AsBytes1 {
#[derive(Unaligned)]
#[repr(C)]
struct Unaligned1 {
- aligned: u16,
+ aligned: AU16,
}
// This specifically tests a bug we had in an old version of the code in which
@@ -47,11 +60,11 @@ struct Unaligned1 {
#[repr(C)]
struct Unaligned2 {
unaligned: u8,
- aligned: u16,
+ aligned: AU16,
}
#[derive(Unaligned)]
#[repr(transparent)]
struct Unaligned3 {
- aligned: u16,
+ aligned: AU16,
}
diff --git a/tests/ui-msrv/late_compile_pass.stderr b/tests/ui-msrv/late_compile_pass.stderr
index a692474..29d20e4 100644
--- a/tests/ui-msrv/late_compile_pass.stderr
+++ b/tests/ui-msrv/late_compile_pass.stderr
@@ -1,66 +1,66 @@
-error[E0277]: the trait bound `AsBytes1: HasPadding<false>` is not satisfied
- --> tests/ui-msrv/late_compile_pass.rs:27:10
+error[E0277]: the trait bound `NotZerocopy: FromZeroes` is not satisfied
+ --> tests/ui-msrv/late_compile_pass.rs:23:10
|
-27 | #[derive(AsBytes)]
- | ^^^^^^^ the trait `HasPadding<false>` is not implemented for `AsBytes1`
+23 | #[derive(FromZeroes)]
+ | ^^^^^^^^^^ the trait `FromZeroes` is not implemented for `NotZerocopy`
|
- = help: the following implementations were found:
- <AsBytes1 as HasPadding<true>>
-note: required by a bound in `assert_no_padding`
- --> tests/ui-msrv/late_compile_pass.rs:27:10
+ = 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:32:10
|
-27 | #[derive(AsBytes)]
- | ^^^^^^^ required by this bound in `assert_no_padding`
- = note: this error originates in the derive macro `AsBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
+32 | #[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 `&'static str: FromBytes` is not satisfied
- --> tests/ui-msrv/late_compile_pass.rs:18:10
+error[E0277]: the trait bound `FromBytes1: FromZeroes` is not satisfied
+ --> tests/ui-msrv/late_compile_pass.rs:32:10
|
-18 | #[derive(FromBytes)]
- | ^^^^^^^^^ the trait `FromBytes` is not implemented for `&'static str`
+32 | #[derive(FromBytes)]
+ | ^^^^^^^^^ the trait `FromZeroes` is not implemented for `FromBytes1`
|
-note: required by a bound in `ImplementsFromBytes`
- --> tests/ui-msrv/late_compile_pass.rs:18:10
+note: required by a bound in `FromBytes`
+ --> $WORKSPACE/src/lib.rs
|
-18 | #[derive(FromBytes)]
- | ^^^^^^^^^ required by this bound in `ImplementsFromBytes`
+ | 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 `u16: Unaligned` is not satisfied
- --> tests/ui-msrv/late_compile_pass.rs:38:10
+error[E0277]: the trait bound `NotZerocopy: AsBytes` is not satisfied
+ --> tests/ui-msrv/late_compile_pass.rs:41:10
|
-38 | #[derive(Unaligned)]
- | ^^^^^^^^^ the trait `Unaligned` is not implemented for `u16`
+41 | #[derive(AsBytes)]
+ | ^^^^^^^ the trait `AsBytes` is not implemented for `NotZerocopy`
|
-note: required by a bound in `<Unaligned1 as Unaligned>::only_derive_is_allowed_to_implement_this_trait::ImplementsUnaligned`
- --> tests/ui-msrv/late_compile_pass.rs:38:10
+ = 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:51:10
+ |
+51 | #[derive(Unaligned)]
+ | ^^^^^^^^^ the trait `Unaligned` is not implemented for `AU16`
|
-38 | #[derive(Unaligned)]
- | ^^^^^^^^^ required by this bound in `<Unaligned1 as Unaligned>::only_derive_is_allowed_to_implement_this_trait::ImplementsUnaligned`
+ = 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 `u16: Unaligned` is not satisfied
- --> tests/ui-msrv/late_compile_pass.rs:46:10
+error[E0277]: the trait bound `AU16: Unaligned` is not satisfied
+ --> tests/ui-msrv/late_compile_pass.rs:59:10
|
-46 | #[derive(Unaligned)]
- | ^^^^^^^^^ the trait `Unaligned` is not implemented for `u16`
+59 | #[derive(Unaligned)]
+ | ^^^^^^^^^ the trait `Unaligned` is not implemented for `AU16`
|
-note: required by a bound in `<Unaligned2 as Unaligned>::only_derive_is_allowed_to_implement_this_trait::ImplementsUnaligned`
- --> tests/ui-msrv/late_compile_pass.rs:46:10
- |
-46 | #[derive(Unaligned)]
- | ^^^^^^^^^ required by this bound in `<Unaligned2 as Unaligned>::only_derive_is_allowed_to_implement_this_trait::ImplementsUnaligned`
+ = 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 `u16: Unaligned` is not satisfied
- --> tests/ui-msrv/late_compile_pass.rs:53:10
- |
-53 | #[derive(Unaligned)]
- | ^^^^^^^^^ the trait `Unaligned` is not implemented for `u16`
+error[E0277]: the trait bound `AU16: Unaligned` is not satisfied
+ --> tests/ui-msrv/late_compile_pass.rs:66:10
|
-note: required by a bound in `<Unaligned3 as Unaligned>::only_derive_is_allowed_to_implement_this_trait::ImplementsUnaligned`
- --> tests/ui-msrv/late_compile_pass.rs:53:10
+66 | #[derive(Unaligned)]
+ | ^^^^^^^^^ the trait `Unaligned` is not implemented for `AU16`
|
-53 | #[derive(Unaligned)]
- | ^^^^^^^^^ required by this bound in `<Unaligned3 as Unaligned>::only_derive_is_allowed_to_implement_this_trait::ImplementsUnaligned`
+ = help: see issue #48214
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/tests/ui-msrv/struct.rs b/tests/ui-msrv/struct.rs
index ee8fd06..29aa0e8 100644
--- a/tests/ui-msrv/struct.rs
+++ b/tests/ui-msrv/struct.rs
@@ -5,6 +5,11 @@
#[macro_use]
extern crate zerocopy;
+#[path = "../util.rs"]
+mod util;
+
+use self::util::AU16;
+
fn main() {}
//
@@ -15,6 +20,13 @@ fn main() {}
#[repr(C)]
struct AsBytes1<T>(T);
+#[derive(AsBytes)]
+#[repr(C)]
+struct AsBytes2 {
+ foo: u8,
+ bar: AU16,
+}
+
//
// Unaligned errors
//
diff --git a/tests/ui-msrv/struct.stderr b/tests/ui-msrv/struct.stderr
index c3e91d4..fe73b80 100644
--- a/tests/ui-msrv/struct.stderr
+++ b/tests/ui-msrv/struct.stderr
@@ -1,49 +1,54 @@
-error: unsupported on types with type parameters
- --> tests/ui-msrv/struct.rs:14:10
+error: unsupported on generic structs that are not repr(transparent) or repr(packed)
+ --> tests/ui-msrv/struct.rs:19:10
|
-14 | #[derive(AsBytes)]
+19 | #[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:23:11
+ --> tests/ui-msrv/struct.rs:35:11
|
-23 | #[repr(C, align(2))]
+35 | #[repr(C, align(2))]
| ^^^^^^^^
error: cannot derive Unaligned with repr(align(N > 1))
- --> tests/ui-msrv/struct.rs:27:21
+ --> tests/ui-msrv/struct.rs:39:21
|
-27 | #[repr(transparent, align(2))]
+39 | #[repr(transparent, align(2))]
| ^^^^^^^^
error: cannot derive Unaligned with repr(align(N > 1))
- --> tests/ui-msrv/struct.rs:33:16
+ --> tests/ui-msrv/struct.rs:45:16
|
-33 | #[repr(packed, align(2))]
+45 | #[repr(packed, align(2))]
| ^^^^^^^^
error: cannot derive Unaligned with repr(align(N > 1))
- --> tests/ui-msrv/struct.rs:37:18
+ --> tests/ui-msrv/struct.rs:49:18
|
-37 | #[repr(align(1), align(2))]
+49 | #[repr(align(1), align(2))]
| ^^^^^^^^
error: cannot derive Unaligned with repr(align(N > 1))
- --> tests/ui-msrv/struct.rs:41:8
+ --> tests/ui-msrv/struct.rs:53:8
|
-41 | #[repr(align(2), align(4))]
+53 | #[repr(align(2), align(4))]
| ^^^^^^^^
error[E0692]: transparent struct cannot have other repr hints
- --> tests/ui-msrv/struct.rs:27:8
+ --> tests/ui-msrv/struct.rs:39:8
|
-27 | #[repr(transparent, align(2))]
+39 | #[repr(transparent, align(2))]
| ^^^^^^^^^^^ ^^^^^^^^
-error[E0587]: type has conflicting packed and align representation hints
- --> tests/ui-msrv/struct.rs:34:1
+error[E0277]: the trait bound `HasPadding<AsBytes2, true>: ShouldBe<false>` is not satisfied
+ --> tests/ui-msrv/struct.rs:23:10
|
-34 | struct Unaligned3;
- | ^^^^^^^^^^^^^^^^^^
+23 | #[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)
diff --git a/tests/ui-msrv/union.rs b/tests/ui-msrv/union.rs
index 0252cbe..e7761e0 100644
--- a/tests/ui-msrv/union.rs
+++ b/tests/ui-msrv/union.rs
@@ -5,6 +5,10 @@
#[macro_use]
extern crate zerocopy;
+#[path = "../util.rs"]
+mod util;
+
+use self::util::AU16;
use std::mem::ManuallyDrop;
fn main() {}
@@ -21,7 +25,7 @@ union AsBytes1<T> {
#[derive(AsBytes)]
#[repr(C)]
-union AsBytes {
+union AsBytes2 {
foo: u8,
bar: [u8; 2],
}
@@ -34,7 +38,7 @@ union AsBytes {
#[repr(C, align(2))]
union Unaligned1 {
foo: i16,
- bar: u16,
+ bar: AU16,
}
// Transparent unions are unstable; see issue #60405
diff --git a/tests/ui-msrv/union.stderr b/tests/ui-msrv/union.stderr
index 56b72be..711b8e2 100644
--- a/tests/ui-msrv/union.stderr
+++ b/tests/ui-msrv/union.stderr
@@ -1,54 +1,42 @@
error: unsupported on types with type parameters
- --> tests/ui-msrv/union.rs:16:10
+ --> tests/ui-msrv/union.rs:20:10
|
-16 | #[derive(AsBytes)]
+20 | #[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:34:11
+ --> tests/ui-msrv/union.rs:38:11
|
-34 | #[repr(C, align(2))]
+38 | #[repr(C, align(2))]
| ^^^^^^^^
error: cannot derive Unaligned with repr(align(N > 1))
- --> tests/ui-msrv/union.rs:50:16
+ --> tests/ui-msrv/union.rs:54:16
|
-50 | #[repr(packed, align(2))]
+54 | #[repr(packed, align(2))]
| ^^^^^^^^
error: cannot derive Unaligned with repr(align(N > 1))
- --> tests/ui-msrv/union.rs:56:18
+ --> tests/ui-msrv/union.rs:60:18
|
-56 | #[repr(align(1), align(2))]
+60 | #[repr(align(1), align(2))]
| ^^^^^^^^
error: cannot derive Unaligned with repr(align(N > 1))
- --> tests/ui-msrv/union.rs:62:8
+ --> tests/ui-msrv/union.rs:66:8
|
-62 | #[repr(align(2), align(4))]
+66 | #[repr(align(2), align(4))]
| ^^^^^^^^
-error[E0277]: the trait bound `AsBytes: FieldsAreSameSize<true>` is not satisfied
- --> tests/ui-msrv/union.rs:22:10
+error[E0277]: the trait bound `HasPadding<AsBytes2, true>: ShouldBe<false>` is not satisfied
+ --> tests/ui-msrv/union.rs:26:10
|
-22 | #[derive(AsBytes)]
- | ^^^^^^^ the trait `FieldsAreSameSize<true>` is not implemented for `AsBytes`
+26 | #[derive(AsBytes)]
+ | ^^^^^^^ the trait `ShouldBe<false>` is not implemented for `HasPadding<AsBytes2, true>`
|
= help: the following implementations were found:
- <AsBytes as FieldsAreSameSize<false>>
-note: required by a bound in `assert_fields_are_same_size`
- --> tests/ui-msrv/union.rs:22:10
- |
-22 | #[derive(AsBytes)]
- | ^^^^^^^ required by this bound in `assert_fields_are_same_size`
+ <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[E0587]: type has conflicting packed and align representation hints
- --> tests/ui-msrv/union.rs:51:1
- |
-51 | / union Unaligned3 {
-52 | | foo: u8,
-53 | | }
- | |_^
diff --git a/tests/ui-nightly/derive_transparent.rs b/tests/ui-nightly/derive_transparent.rs
new file mode 100644
index 0000000..a99f92c
--- /dev/null
+++ b/tests/ui-nightly/derive_transparent.rs
@@ -0,0 +1,36 @@
+// Copyright 2019 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.
+
+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);
diff --git a/tests/ui-nightly/derive_transparent.stderr b/tests/ui-nightly/derive_transparent.stderr
new file mode 100644
index 0000000..5a7d507
--- /dev/null
+++ b/tests/ui-nightly/derive_transparent.stderr
@@ -0,0 +1,111 @@
+error[E0277]: the trait bound `NotZerocopy: FromZeroes` is not satisfied
+ --> tests/ui-nightly/derive_transparent.rs:33:18
+ |
+33 | assert_impl_all!(TransparentStruct<NotZerocopy>: FromZeroes);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `FromZeroes` is not implemented for `NotZerocopy`
+ |
+ = help: the following other types implement trait `FromZeroes`:
+ ()
+ AU16
+ F32<O>
+ F64<O>
+ I128<O>
+ I16<O>
+ I32<O>
+ I64<O>
+ and $N others
+note: required for `TransparentStruct<NotZerocopy>` to implement `FromZeroes`
+ --> tests/ui-nightly/derive_transparent.rs:23:19
+ |
+23 | #[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:33:1
+ |
+33 | 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:34:18
+ |
+34 | assert_impl_all!(TransparentStruct<NotZerocopy>: FromBytes);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `FromBytes` is not implemented for `NotZerocopy`
+ |
+ = help: the following other types implement trait `FromBytes`:
+ ()
+ AU16
+ F32<O>
+ F64<O>
+ I128<O>
+ I16<O>
+ I32<O>
+ I64<O>
+ and $N others
+note: required for `TransparentStruct<NotZerocopy>` to implement `FromBytes`
+ --> tests/ui-nightly/derive_transparent.rs:23:31
+ |
+23 | #[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:34:1
+ |
+34 | 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:35:18
+ |
+35 | assert_impl_all!(TransparentStruct<NotZerocopy>: AsBytes);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `AsBytes` is not implemented for `NotZerocopy`
+ |
+ = help: the following other types implement trait `AsBytes`:
+ ()
+ AU16
+ F32<O>
+ F64<O>
+ I128<O>
+ I16<O>
+ I32<O>
+ I64<O>
+ and $N others
+note: required for `TransparentStruct<NotZerocopy>` to implement `AsBytes`
+ --> tests/ui-nightly/derive_transparent.rs:23:10
+ |
+23 | #[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:35:1
+ |
+35 | 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:36:18
+ |
+36 | assert_impl_all!(TransparentStruct<NotZerocopy>: Unaligned);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Unaligned` is not implemented for `NotZerocopy`
+ |
+ = help: the following other types implement trait `Unaligned`:
+ ()
+ F32<O>
+ F64<O>
+ I128<O>
+ I16<O>
+ I32<O>
+ I64<O>
+ ManuallyDrop<T>
+ and $N others
+note: required for `TransparentStruct<NotZerocopy>` to implement `Unaligned`
+ --> tests/ui-nightly/derive_transparent.rs:23:42
+ |
+23 | #[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:36:1
+ |
+36 | 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)
diff --git a/tests/ui/enum.rs b/tests/ui-nightly/enum.rs
index 188b0a6..c3d1e27 100644
--- a/tests/ui/enum.rs
+++ b/tests/ui-nightly/enum.rs
@@ -11,76 +11,97 @@ fn main() {}
// Generic errors
//
-#[derive(FromBytes)]
+#[derive(FromZeroes, FromBytes)]
#[repr("foo")]
enum Generic1 {
A,
}
-#[derive(FromBytes)]
+#[derive(FromZeroes, FromBytes)]
#[repr(foo)]
enum Generic2 {
A,
}
-#[derive(FromBytes)]
+#[derive(FromZeroes, FromBytes)]
#[repr(transparent)]
enum Generic3 {
A,
}
-#[derive(FromBytes)]
+#[derive(FromZeroes, FromBytes)]
#[repr(u8, u16)]
enum Generic4 {
A,
}
-#[derive(FromBytes)]
+#[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(FromBytes)]
+#[derive(FromZeroes, FromBytes)]
#[repr(C)]
enum FromBytes1 {
A,
}
-#[derive(FromBytes)]
+#[derive(FromZeroes, FromBytes)]
#[repr(usize)]
enum FromBytes2 {
A,
}
-#[derive(FromBytes)]
+#[derive(FromZeroes, FromBytes)]
#[repr(isize)]
enum FromBytes3 {
A,
}
-#[derive(FromBytes)]
+#[derive(FromZeroes, FromBytes)]
#[repr(u32)]
enum FromBytes4 {
A,
}
-#[derive(FromBytes)]
+#[derive(FromZeroes, FromBytes)]
#[repr(i32)]
enum FromBytes5 {
A,
}
-#[derive(FromBytes)]
+#[derive(FromZeroes, FromBytes)]
#[repr(u64)]
enum FromBytes6 {
A,
}
-#[derive(FromBytes)]
+#[derive(FromZeroes, FromBytes)]
#[repr(i64)]
enum FromBytes7 {
A,
diff --git a/tests/ui/enum.stderr b/tests/ui-nightly/enum.stderr
index eeaee34..0c291b5 100644
--- a/tests/ui/enum.stderr
+++ b/tests/ui-nightly/enum.stderr
@@ -1,163 +1,189 @@
error: unrecognized representation hint
- --> tests/ui/enum.rs:15:8
+ --> tests/ui-nightly/enum.rs:15:8
|
15 | #[repr("foo")]
| ^^^^^
error: unrecognized representation hint
- --> tests/ui/enum.rs:21:8
+ --> tests/ui-nightly/enum.rs:21:8
|
21 | #[repr(foo)]
| ^^^
error: unsupported representation for deriving FromBytes, AsBytes, or Unaligned on an enum
- --> tests/ui/enum.rs:27:8
+ --> tests/ui-nightly/enum.rs:27:8
|
27 | #[repr(transparent)]
| ^^^^^^^^^^^
error: conflicting representation hints
- --> tests/ui/enum.rs:33:8
+ --> tests/ui-nightly/enum.rs:33:8
|
33 | #[repr(u8, u16)]
| ^^^^^^^
error: must have a non-align #[repr(...)] attribute in order to guarantee this type's memory layout
- --> tests/ui/enum.rs:38:10
+ --> tests/ui-nightly/enum.rs:38:22
|
-38 | #[derive(FromBytes)]
- | ^^^^^^^^^
+38 | #[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:48:1
+ |
+48 | / enum FromZeroes1 {
+49 | | A(u8),
+50 | | }
+ | |_^
+
+error: only C-like enums can implement FromZeroes
+ --> tests/ui-nightly/enum.rs:53:1
+ |
+53 | / enum FromZeroes2 {
+54 | | A,
+55 | | B(u8),
+56 | | }
+ | |_^
+
+error: FromZeroes only supported on enums with a variant that has a discriminant of `0`
+ --> tests/ui-nightly/enum.rs:59:1
+ |
+59 | / enum FromZeroes3 {
+60 | | A = 1,
+61 | | B,
+62 | | }
+ | |_^
+
error: FromBytes requires repr of "u8", "u16", "i8", or "i16"
- --> tests/ui/enum.rs:48:8
+ --> tests/ui-nightly/enum.rs:69:8
|
-48 | #[repr(C)]
+69 | #[repr(C)]
| ^
error: FromBytes requires repr of "u8", "u16", "i8", or "i16"
- --> tests/ui/enum.rs:54:8
+ --> tests/ui-nightly/enum.rs:75:8
|
-54 | #[repr(usize)]
+75 | #[repr(usize)]
| ^^^^^
error: FromBytes requires repr of "u8", "u16", "i8", or "i16"
- --> tests/ui/enum.rs:60:8
+ --> tests/ui-nightly/enum.rs:81:8
|
-60 | #[repr(isize)]
+81 | #[repr(isize)]
| ^^^^^
error: FromBytes requires repr of "u8", "u16", "i8", or "i16"
- --> tests/ui/enum.rs:66:8
+ --> tests/ui-nightly/enum.rs:87:8
|
-66 | #[repr(u32)]
+87 | #[repr(u32)]
| ^^^
error: FromBytes requires repr of "u8", "u16", "i8", or "i16"
- --> tests/ui/enum.rs:72:8
+ --> tests/ui-nightly/enum.rs:93:8
|
-72 | #[repr(i32)]
+93 | #[repr(i32)]
| ^^^
error: FromBytes requires repr of "u8", "u16", "i8", or "i16"
- --> tests/ui/enum.rs:78:8
+ --> tests/ui-nightly/enum.rs:99:8
|
-78 | #[repr(u64)]
+99 | #[repr(u64)]
| ^^^
error: FromBytes requires repr of "u8", "u16", "i8", or "i16"
- --> tests/ui/enum.rs:84:8
- |
-84 | #[repr(i64)]
- | ^^^
+ --> tests/ui-nightly/enum.rs:105:8
+ |
+105 | #[repr(i64)]
+ | ^^^
error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1)))
- --> tests/ui/enum.rs:94:8
- |
-94 | #[repr(C)]
- | ^
+ --> tests/ui-nightly/enum.rs:115:8
+ |
+115 | #[repr(C)]
+ | ^
error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1)))
- --> tests/ui/enum.rs:100:8
+ --> tests/ui-nightly/enum.rs:121:8
|
-100 | #[repr(u16)]
+121 | #[repr(u16)]
| ^^^
error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1)))
- --> tests/ui/enum.rs:106:8
+ --> tests/ui-nightly/enum.rs:127:8
|
-106 | #[repr(i16)]
+127 | #[repr(i16)]
| ^^^
error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1)))
- --> tests/ui/enum.rs:112:8
+ --> tests/ui-nightly/enum.rs:133:8
|
-112 | #[repr(u32)]
+133 | #[repr(u32)]
| ^^^
error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1)))
- --> tests/ui/enum.rs:118:8
+ --> tests/ui-nightly/enum.rs:139:8
|
-118 | #[repr(i32)]
+139 | #[repr(i32)]
| ^^^
error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1)))
- --> tests/ui/enum.rs:124:8
+ --> tests/ui-nightly/enum.rs:145:8
|
-124 | #[repr(u64)]
+145 | #[repr(u64)]
| ^^^
error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1)))
- --> tests/ui/enum.rs:130:8
+ --> tests/ui-nightly/enum.rs:151:8
|
-130 | #[repr(i64)]
+151 | #[repr(i64)]
| ^^^
error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1)))
- --> tests/ui/enum.rs:136:8
+ --> tests/ui-nightly/enum.rs:157:8
|
-136 | #[repr(usize)]
+157 | #[repr(usize)]
| ^^^^^
error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1)))
- --> tests/ui/enum.rs:142:8
+ --> tests/ui-nightly/enum.rs:163:8
|
-142 | #[repr(isize)]
+163 | #[repr(isize)]
| ^^^^^
error: cannot derive Unaligned with repr(align(N > 1))
- --> tests/ui/enum.rs:148:12
+ --> tests/ui-nightly/enum.rs:169:12
|
-148 | #[repr(u8, align(2))]
+169 | #[repr(u8, align(2))]
| ^^^^^^^^
error: cannot derive Unaligned with repr(align(N > 1))
- --> tests/ui/enum.rs:154:12
+ --> tests/ui-nightly/enum.rs:175:12
|
-154 | #[repr(i8, align(2))]
+175 | #[repr(i8, align(2))]
| ^^^^^^^^
error: cannot derive Unaligned with repr(align(N > 1))
- --> tests/ui/enum.rs:160:18
+ --> tests/ui-nightly/enum.rs:181:18
|
-160 | #[repr(align(1), align(2))]
+181 | #[repr(align(1), align(2))]
| ^^^^^^^^
error: cannot derive Unaligned with repr(align(N > 1))
- --> tests/ui/enum.rs:166:8
+ --> tests/ui-nightly/enum.rs:187:8
|
-166 | #[repr(align(2), align(4))]
+187 | #[repr(align(2), align(4))]
| ^^^^^^^^
error[E0565]: meta item in `repr` must be an identifier
- --> tests/ui/enum.rs:15:8
+ --> tests/ui-nightly/enum.rs:15:8
|
15 | #[repr("foo")]
| ^^^^^
error[E0552]: unrecognized representation hint
- --> tests/ui/enum.rs:21:8
+ --> tests/ui-nightly/enum.rs:21:8
|
21 | #[repr(foo)]
| ^^^
@@ -165,11 +191,11 @@ error[E0552]: unrecognized representation hint
= help: valid reprs are `C`, `align`, `packed`, `transparent`, `simd`, `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize`
error[E0566]: conflicting representation hints
- --> tests/ui/enum.rs:33:8
+ --> tests/ui-nightly/enum.rs:33:8
|
33 | #[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>
+ = note: `#[deny(conflicting_repr_hints)]` on by default
diff --git a/tests/ui/enum_from_bytes_u16_too_few.rs.disabled b/tests/ui-nightly/enum_from_bytes_u16_too_few.rs.disabled
index 99bc764..99bc764 100644
--- a/tests/ui/enum_from_bytes_u16_too_few.rs.disabled
+++ b/tests/ui-nightly/enum_from_bytes_u16_too_few.rs.disabled
diff --git a/tests/ui/enum_from_bytes_u8_too_few.rs b/tests/ui-nightly/enum_from_bytes_u8_too_few.rs
index 4f54ec7..4f54ec7 100644
--- a/tests/ui/enum_from_bytes_u8_too_few.rs
+++ b/tests/ui-nightly/enum_from_bytes_u8_too_few.rs
diff --git a/tests/ui/enum_from_bytes_u8_too_few.stderr b/tests/ui-nightly/enum_from_bytes_u8_too_few.stderr
index b75f6c2..1ecba21 100644
--- a/tests/ui/enum_from_bytes_u8_too_few.stderr
+++ b/tests/ui-nightly/enum_from_bytes_u8_too_few.stderr
@@ -1,5 +1,5 @@
error: FromBytes only supported on repr(u8) enum with 256 variants
- --> tests/ui/enum_from_bytes_u8_too_few.rs:11:1
+ --> tests/ui-nightly/enum_from_bytes_u8_too_few.rs:11:1
|
11 | / #[repr(u8)]
12 | | enum Foo {
diff --git a/tests/ui/late_compile_pass.rs b/tests/ui-nightly/late_compile_pass.rs
index 3a99c76..1b4c603 100644
--- a/tests/ui/late_compile_pass.rs
+++ b/tests/ui-nightly/late_compile_pass.rs
@@ -5,6 +5,11 @@
#[macro_use]
extern crate zerocopy;
+#[path = "../util.rs"]
+mod util;
+
+use self::util::{NotZerocopy, AU16};
+
fn main() {}
// These tests cause errors which are generated by a later compilation pass than
@@ -12,12 +17,21 @@ fn main() {}
// 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 {
- not_from_bytes: &'static str,
+ value: NotZerocopy,
}
//
@@ -27,8 +41,7 @@ struct FromBytes1 {
#[derive(AsBytes)]
#[repr(C)]
struct AsBytes1 {
- a: u8,
- b: u16,
+ value: NotZerocopy,
}
//
@@ -38,7 +51,7 @@ struct AsBytes1 {
#[derive(Unaligned)]
#[repr(C)]
struct Unaligned1 {
- aligned: u16,
+ aligned: AU16,
}
// This specifically tests a bug we had in an old version of the code in which
@@ -47,11 +60,11 @@ struct Unaligned1 {
#[repr(C)]
struct Unaligned2 {
unaligned: u8,
- aligned: u16,
+ aligned: AU16,
}
#[derive(Unaligned)]
#[repr(transparent)]
struct Unaligned3 {
- aligned: u16,
+ aligned: AU16,
}
diff --git a/tests/ui-nightly/late_compile_pass.stderr b/tests/ui-nightly/late_compile_pass.stderr
new file mode 100644
index 0000000..fbf9da7
--- /dev/null
+++ b/tests/ui-nightly/late_compile_pass.stderr
@@ -0,0 +1,142 @@
+error[E0277]: the trait bound `NotZerocopy: FromZeroes` is not satisfied
+ --> tests/ui-nightly/late_compile_pass.rs:23:10
+ |
+23 | #[derive(FromZeroes)]
+ | ^^^^^^^^^^ the trait `FromZeroes` is not implemented for `NotZerocopy`
+ |
+ = help: the following other types implement trait `FromZeroes`:
+ ()
+ AU16
+ F32<O>
+ F64<O>
+ FromZeroes1
+ I128<O>
+ I16<O>
+ I32<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 `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:32:10
+ |
+32 | #[derive(FromBytes)]
+ | ^^^^^^^^^ the trait `FromBytes` is not implemented for `NotZerocopy`
+ |
+ = help: the following other types implement trait `FromBytes`:
+ ()
+ AU16
+ F32<O>
+ F64<O>
+ FromBytes1
+ I128<O>
+ I16<O>
+ I32<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 `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:32:10
+ |
+32 | #[derive(FromBytes)]
+ | ^^^^^^^^^ the trait `FromZeroes` is not implemented for `FromBytes1`
+ |
+ = help: the following other types implement trait `FromZeroes`:
+ ()
+ AU16
+ F32<O>
+ F64<O>
+ FromZeroes1
+ I128<O>
+ I16<O>
+ I32<O>
+ 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:41:10
+ |
+41 | #[derive(AsBytes)]
+ | ^^^^^^^ the trait `AsBytes` is not implemented for `NotZerocopy`
+ |
+ = help: the following other types implement trait `AsBytes`:
+ ()
+ AU16
+ AsBytes1
+ F32<O>
+ F64<O>
+ I128<O>
+ I16<O>
+ I32<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 `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:51:10
+ |
+51 | #[derive(Unaligned)]
+ | ^^^^^^^^^ the trait `Unaligned` is not implemented for `AU16`
+ |
+ = help: the following other types implement trait `Unaligned`:
+ ()
+ F32<O>
+ F64<O>
+ I128<O>
+ I16<O>
+ I32<O>
+ I64<O>
+ ManuallyDrop<T>
+ 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:59:10
+ |
+59 | #[derive(Unaligned)]
+ | ^^^^^^^^^ the trait `Unaligned` is not implemented for `AU16`
+ |
+ = help: the following other types implement trait `Unaligned`:
+ ()
+ F32<O>
+ F64<O>
+ I128<O>
+ I16<O>
+ I32<O>
+ I64<O>
+ ManuallyDrop<T>
+ 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:66:10
+ |
+66 | #[derive(Unaligned)]
+ | ^^^^^^^^^ the trait `Unaligned` is not implemented for `AU16`
+ |
+ = help: the following other types implement trait `Unaligned`:
+ ()
+ F32<O>
+ F64<O>
+ I128<O>
+ I16<O>
+ I32<O>
+ I64<O>
+ ManuallyDrop<T>
+ 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)
diff --git a/tests/ui/struct.rs b/tests/ui-nightly/struct.rs
index ee8fd06..29aa0e8 100644
--- a/tests/ui/struct.rs
+++ b/tests/ui-nightly/struct.rs
@@ -5,6 +5,11 @@
#[macro_use]
extern crate zerocopy;
+#[path = "../util.rs"]
+mod util;
+
+use self::util::AU16;
+
fn main() {}
//
@@ -15,6 +20,13 @@ fn main() {}
#[repr(C)]
struct AsBytes1<T>(T);
+#[derive(AsBytes)]
+#[repr(C)]
+struct AsBytes2 {
+ foo: u8,
+ bar: AU16,
+}
+
//
// Unaligned errors
//
diff --git a/tests/ui-nightly/struct.stderr b/tests/ui-nightly/struct.stderr
new file mode 100644
index 0000000..a75d070
--- /dev/null
+++ b/tests/ui-nightly/struct.stderr
@@ -0,0 +1,54 @@
+error: unsupported on generic structs that are not repr(transparent) or repr(packed)
+ --> tests/ui-nightly/struct.rs:19:10
+ |
+19 | #[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:35:11
+ |
+35 | #[repr(C, align(2))]
+ | ^^^^^^^^
+
+error: cannot derive Unaligned with repr(align(N > 1))
+ --> tests/ui-nightly/struct.rs:39:21
+ |
+39 | #[repr(transparent, align(2))]
+ | ^^^^^^^^
+
+error: cannot derive Unaligned with repr(align(N > 1))
+ --> tests/ui-nightly/struct.rs:45:16
+ |
+45 | #[repr(packed, align(2))]
+ | ^^^^^^^^
+
+error: cannot derive Unaligned with repr(align(N > 1))
+ --> tests/ui-nightly/struct.rs:49:18
+ |
+49 | #[repr(align(1), align(2))]
+ | ^^^^^^^^
+
+error: cannot derive Unaligned with repr(align(N > 1))
+ --> tests/ui-nightly/struct.rs:53:8
+ |
+53 | #[repr(align(2), align(4))]
+ | ^^^^^^^^
+
+error[E0692]: transparent struct cannot have other repr hints
+ --> tests/ui-nightly/struct.rs:39:8
+ |
+39 | #[repr(transparent, align(2))]
+ | ^^^^^^^^^^^ ^^^^^^^^
+
+error[E0277]: the trait bound `HasPadding<AsBytes2, true>: ShouldBe<false>` is not satisfied
+ --> tests/ui-nightly/struct.rs:23:10
+ |
+23 | #[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
+ = 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)
diff --git a/tests/ui/union.rs b/tests/ui-nightly/union.rs
index 0252cbe..e7761e0 100644
--- a/tests/ui/union.rs
+++ b/tests/ui-nightly/union.rs
@@ -5,6 +5,10 @@
#[macro_use]
extern crate zerocopy;
+#[path = "../util.rs"]
+mod util;
+
+use self::util::AU16;
use std::mem::ManuallyDrop;
fn main() {}
@@ -21,7 +25,7 @@ union AsBytes1<T> {
#[derive(AsBytes)]
#[repr(C)]
-union AsBytes {
+union AsBytes2 {
foo: u8,
bar: [u8; 2],
}
@@ -34,7 +38,7 @@ union AsBytes {
#[repr(C, align(2))]
union Unaligned1 {
foo: i16,
- bar: u16,
+ bar: AU16,
}
// Transparent unions are unstable; see issue #60405
diff --git a/tests/ui-nightly/union.stderr b/tests/ui-nightly/union.stderr
new file mode 100644
index 0000000..9c1f8dd
--- /dev/null
+++ b/tests/ui-nightly/union.stderr
@@ -0,0 +1,42 @@
+error: unsupported on types with type parameters
+ --> tests/ui-nightly/union.rs:20:10
+ |
+20 | #[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:38:11
+ |
+38 | #[repr(C, align(2))]
+ | ^^^^^^^^
+
+error: cannot derive Unaligned with repr(align(N > 1))
+ --> tests/ui-nightly/union.rs:54:16
+ |
+54 | #[repr(packed, align(2))]
+ | ^^^^^^^^
+
+error: cannot derive Unaligned with repr(align(N > 1))
+ --> tests/ui-nightly/union.rs:60:18
+ |
+60 | #[repr(align(1), align(2))]
+ | ^^^^^^^^
+
+error: cannot derive Unaligned with repr(align(N > 1))
+ --> tests/ui-nightly/union.rs:66:8
+ |
+66 | #[repr(align(2), align(4))]
+ | ^^^^^^^^
+
+error[E0277]: the trait bound `HasPadding<AsBytes2, true>: ShouldBe<false>` is not satisfied
+ --> tests/ui-nightly/union.rs:26:10
+ |
+26 | #[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
+ = 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)
diff --git a/tests/ui-stable/derive_transparent.rs b/tests/ui-stable/derive_transparent.rs
new file mode 100644
index 0000000..a99f92c
--- /dev/null
+++ b/tests/ui-stable/derive_transparent.rs
@@ -0,0 +1,36 @@
+// Copyright 2019 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.
+
+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);
diff --git a/tests/ui-stable/derive_transparent.stderr b/tests/ui-stable/derive_transparent.stderr
new file mode 100644
index 0000000..3810def
--- /dev/null
+++ b/tests/ui-stable/derive_transparent.stderr
@@ -0,0 +1,111 @@
+error[E0277]: the trait bound `NotZerocopy: FromZeroes` is not satisfied
+ --> tests/ui-stable/derive_transparent.rs:33:18
+ |
+33 | assert_impl_all!(TransparentStruct<NotZerocopy>: FromZeroes);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `FromZeroes` is not implemented for `NotZerocopy`
+ |
+ = help: the following other types implement trait `FromZeroes`:
+ ()
+ AU16
+ F32<O>
+ F64<O>
+ I128<O>
+ I16<O>
+ I32<O>
+ I64<O>
+ and $N others
+note: required for `TransparentStruct<NotZerocopy>` to implement `FromZeroes`
+ --> tests/ui-stable/derive_transparent.rs:23:19
+ |
+23 | #[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:33:1
+ |
+33 | 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:34:18
+ |
+34 | assert_impl_all!(TransparentStruct<NotZerocopy>: FromBytes);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `FromBytes` is not implemented for `NotZerocopy`
+ |
+ = help: the following other types implement trait `FromBytes`:
+ ()
+ AU16
+ F32<O>
+ F64<O>
+ I128<O>
+ I16<O>
+ I32<O>
+ I64<O>
+ and $N others
+note: required for `TransparentStruct<NotZerocopy>` to implement `FromBytes`
+ --> tests/ui-stable/derive_transparent.rs:23:31
+ |
+23 | #[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:34:1
+ |
+34 | 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:35:18
+ |
+35 | assert_impl_all!(TransparentStruct<NotZerocopy>: AsBytes);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `AsBytes` is not implemented for `NotZerocopy`
+ |
+ = help: the following other types implement trait `AsBytes`:
+ ()
+ AU16
+ F32<O>
+ F64<O>
+ I128<O>
+ I16<O>
+ I32<O>
+ I64<O>
+ and $N others
+note: required for `TransparentStruct<NotZerocopy>` to implement `AsBytes`
+ --> tests/ui-stable/derive_transparent.rs:23:10
+ |
+23 | #[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:35:1
+ |
+35 | 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:36:18
+ |
+36 | assert_impl_all!(TransparentStruct<NotZerocopy>: Unaligned);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Unaligned` is not implemented for `NotZerocopy`
+ |
+ = help: the following other types implement trait `Unaligned`:
+ ()
+ F32<O>
+ F64<O>
+ I128<O>
+ I16<O>
+ I32<O>
+ I64<O>
+ ManuallyDrop<T>
+ and $N others
+note: required for `TransparentStruct<NotZerocopy>` to implement `Unaligned`
+ --> tests/ui-stable/derive_transparent.rs:23:42
+ |
+23 | #[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:36:1
+ |
+36 | 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)
diff --git a/tests/ui-stable/enum.rs b/tests/ui-stable/enum.rs
index 188b0a6..c3d1e27 100644
--- a/tests/ui-stable/enum.rs
+++ b/tests/ui-stable/enum.rs
@@ -11,76 +11,97 @@ fn main() {}
// Generic errors
//
-#[derive(FromBytes)]
+#[derive(FromZeroes, FromBytes)]
#[repr("foo")]
enum Generic1 {
A,
}
-#[derive(FromBytes)]
+#[derive(FromZeroes, FromBytes)]
#[repr(foo)]
enum Generic2 {
A,
}
-#[derive(FromBytes)]
+#[derive(FromZeroes, FromBytes)]
#[repr(transparent)]
enum Generic3 {
A,
}
-#[derive(FromBytes)]
+#[derive(FromZeroes, FromBytes)]
#[repr(u8, u16)]
enum Generic4 {
A,
}
-#[derive(FromBytes)]
+#[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(FromBytes)]
+#[derive(FromZeroes, FromBytes)]
#[repr(C)]
enum FromBytes1 {
A,
}
-#[derive(FromBytes)]
+#[derive(FromZeroes, FromBytes)]
#[repr(usize)]
enum FromBytes2 {
A,
}
-#[derive(FromBytes)]
+#[derive(FromZeroes, FromBytes)]
#[repr(isize)]
enum FromBytes3 {
A,
}
-#[derive(FromBytes)]
+#[derive(FromZeroes, FromBytes)]
#[repr(u32)]
enum FromBytes4 {
A,
}
-#[derive(FromBytes)]
+#[derive(FromZeroes, FromBytes)]
#[repr(i32)]
enum FromBytes5 {
A,
}
-#[derive(FromBytes)]
+#[derive(FromZeroes, FromBytes)]
#[repr(u64)]
enum FromBytes6 {
A,
}
-#[derive(FromBytes)]
+#[derive(FromZeroes, FromBytes)]
#[repr(i64)]
enum FromBytes7 {
A,
diff --git a/tests/ui-stable/enum.stderr b/tests/ui-stable/enum.stderr
index a72d288..1e35fa6 100644
--- a/tests/ui-stable/enum.stderr
+++ b/tests/ui-stable/enum.stderr
@@ -23,131 +23,157 @@ error: conflicting representation hints
| ^
error: must have a non-align #[repr(...)] attribute in order to guarantee this type's memory layout
- --> tests/ui-stable/enum.rs:38:10
+ --> tests/ui-stable/enum.rs:38:22
|
-38 | #[derive(FromBytes)]
- | ^^^^^^^^^
+38 | #[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:48:1
+ |
+48 | / enum FromZeroes1 {
+49 | | A(u8),
+50 | | }
+ | |_^
+
+error: only C-like enums can implement FromZeroes
+ --> tests/ui-stable/enum.rs:53:1
+ |
+53 | / enum FromZeroes2 {
+54 | | A,
+55 | | B(u8),
+56 | | }
+ | |_^
+
+error: FromZeroes only supported on enums with a variant that has a discriminant of `0`
+ --> tests/ui-stable/enum.rs:59:1
+ |
+59 | / enum FromZeroes3 {
+60 | | A = 1,
+61 | | B,
+62 | | }
+ | |_^
+
error: FromBytes requires repr of "u8", "u16", "i8", or "i16"
- --> tests/ui-stable/enum.rs:48:8
+ --> tests/ui-stable/enum.rs:69:8
|
-48 | #[repr(C)]
+69 | #[repr(C)]
| ^
error: FromBytes requires repr of "u8", "u16", "i8", or "i16"
- --> tests/ui-stable/enum.rs:54:8
+ --> tests/ui-stable/enum.rs:75:8
|
-54 | #[repr(usize)]
+75 | #[repr(usize)]
| ^^^^^
error: FromBytes requires repr of "u8", "u16", "i8", or "i16"
- --> tests/ui-stable/enum.rs:60:8
+ --> tests/ui-stable/enum.rs:81:8
|
-60 | #[repr(isize)]
+81 | #[repr(isize)]
| ^^^^^
error: FromBytes requires repr of "u8", "u16", "i8", or "i16"
- --> tests/ui-stable/enum.rs:66:8
+ --> tests/ui-stable/enum.rs:87:8
|
-66 | #[repr(u32)]
+87 | #[repr(u32)]
| ^^^
error: FromBytes requires repr of "u8", "u16", "i8", or "i16"
- --> tests/ui-stable/enum.rs:72:8
+ --> tests/ui-stable/enum.rs:93:8
|
-72 | #[repr(i32)]
+93 | #[repr(i32)]
| ^^^
error: FromBytes requires repr of "u8", "u16", "i8", or "i16"
- --> tests/ui-stable/enum.rs:78:8
+ --> tests/ui-stable/enum.rs:99:8
|
-78 | #[repr(u64)]
+99 | #[repr(u64)]
| ^^^
error: FromBytes requires repr of "u8", "u16", "i8", or "i16"
- --> tests/ui-stable/enum.rs:84:8
- |
-84 | #[repr(i64)]
- | ^^^
+ --> tests/ui-stable/enum.rs:105:8
+ |
+105 | #[repr(i64)]
+ | ^^^
error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1)))
- --> tests/ui-stable/enum.rs:94:8
- |
-94 | #[repr(C)]
- | ^
+ --> tests/ui-stable/enum.rs:115:8
+ |
+115 | #[repr(C)]
+ | ^
error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1)))
- --> tests/ui-stable/enum.rs:100:8
+ --> tests/ui-stable/enum.rs:121:8
|
-100 | #[repr(u16)]
+121 | #[repr(u16)]
| ^^^
error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1)))
- --> tests/ui-stable/enum.rs:106:8
+ --> tests/ui-stable/enum.rs:127:8
|
-106 | #[repr(i16)]
+127 | #[repr(i16)]
| ^^^
error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1)))
- --> tests/ui-stable/enum.rs:112:8
+ --> tests/ui-stable/enum.rs:133:8
|
-112 | #[repr(u32)]
+133 | #[repr(u32)]
| ^^^
error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1)))
- --> tests/ui-stable/enum.rs:118:8
+ --> tests/ui-stable/enum.rs:139:8
|
-118 | #[repr(i32)]
+139 | #[repr(i32)]
| ^^^
error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1)))
- --> tests/ui-stable/enum.rs:124:8
+ --> tests/ui-stable/enum.rs:145:8
|
-124 | #[repr(u64)]
+145 | #[repr(u64)]
| ^^^
error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1)))
- --> tests/ui-stable/enum.rs:130:8
+ --> tests/ui-stable/enum.rs:151:8
|
-130 | #[repr(i64)]
+151 | #[repr(i64)]
| ^^^
error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1)))
- --> tests/ui-stable/enum.rs:136:8
+ --> tests/ui-stable/enum.rs:157:8
|
-136 | #[repr(usize)]
+157 | #[repr(usize)]
| ^^^^^
error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1)))
- --> tests/ui-stable/enum.rs:142:8
+ --> tests/ui-stable/enum.rs:163:8
|
-142 | #[repr(isize)]
+163 | #[repr(isize)]
| ^^^^^
error: cannot derive Unaligned with repr(align(N > 1))
- --> tests/ui-stable/enum.rs:148:12
+ --> tests/ui-stable/enum.rs:169:12
|
-148 | #[repr(u8, align(2))]
+169 | #[repr(u8, align(2))]
| ^^^^^^^^
error: cannot derive Unaligned with repr(align(N > 1))
- --> tests/ui-stable/enum.rs:154:12
+ --> tests/ui-stable/enum.rs:175:12
|
-154 | #[repr(i8, align(2))]
+175 | #[repr(i8, align(2))]
| ^^^^^^^^
error: cannot derive Unaligned with repr(align(N > 1))
- --> tests/ui-stable/enum.rs:160:18
+ --> tests/ui-stable/enum.rs:181:18
|
-160 | #[repr(align(1), align(2))]
+181 | #[repr(align(1), align(2))]
| ^^^^^^^^
error: cannot derive Unaligned with repr(align(N > 1))
- --> tests/ui-stable/enum.rs:166:8
+ --> tests/ui-stable/enum.rs:187:8
|
-166 | #[repr(align(2), align(4))]
+187 | #[repr(align(2), align(4))]
| ^^^^^^^^
error[E0565]: meta item in `repr` must be an identifier
@@ -161,6 +187,8 @@ error[E0552]: unrecognized representation hint
|
21 | #[repr(foo)]
| ^^^
+ |
+ = help: valid reprs are `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:33:8
@@ -168,6 +196,6 @@ error[E0566]: conflicting representation hints
33 | #[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>
+ = note: `#[deny(conflicting_repr_hints)]` on by default
diff --git a/tests/ui-stable/late_compile_pass.rs b/tests/ui-stable/late_compile_pass.rs
index 3a99c76..1b4c603 100644
--- a/tests/ui-stable/late_compile_pass.rs
+++ b/tests/ui-stable/late_compile_pass.rs
@@ -5,6 +5,11 @@
#[macro_use]
extern crate zerocopy;
+#[path = "../util.rs"]
+mod util;
+
+use self::util::{NotZerocopy, AU16};
+
fn main() {}
// These tests cause errors which are generated by a later compilation pass than
@@ -12,12 +17,21 @@ fn main() {}
// 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 {
- not_from_bytes: &'static str,
+ value: NotZerocopy,
}
//
@@ -27,8 +41,7 @@ struct FromBytes1 {
#[derive(AsBytes)]
#[repr(C)]
struct AsBytes1 {
- a: u8,
- b: u16,
+ value: NotZerocopy,
}
//
@@ -38,7 +51,7 @@ struct AsBytes1 {
#[derive(Unaligned)]
#[repr(C)]
struct Unaligned1 {
- aligned: u16,
+ aligned: AU16,
}
// This specifically tests a bug we had in an old version of the code in which
@@ -47,11 +60,11 @@ struct Unaligned1 {
#[repr(C)]
struct Unaligned2 {
unaligned: u8,
- aligned: u16,
+ aligned: AU16,
}
#[derive(Unaligned)]
#[repr(transparent)]
struct Unaligned3 {
- aligned: u16,
+ aligned: AU16,
}
diff --git a/tests/ui-stable/late_compile_pass.stderr b/tests/ui-stable/late_compile_pass.stderr
index 6f3bdbe..eab9b97 100644
--- a/tests/ui-stable/late_compile_pass.stderr
+++ b/tests/ui-stable/late_compile_pass.stderr
@@ -1,84 +1,136 @@
-error[E0277]: the trait bound `AsBytes1: HasPadding<false>` is not satisfied
- --> tests/ui-stable/late_compile_pass.rs:27:10
+error[E0277]: the trait bound `NotZerocopy: FromZeroes` is not satisfied
+ --> tests/ui-stable/late_compile_pass.rs:23:10
|
-27 | #[derive(AsBytes)]
- | ^^^^^^^ the trait `HasPadding<false>` is not implemented for `AsBytes1`
+23 | #[derive(FromZeroes)]
+ | ^^^^^^^^^^ the trait `FromZeroes` is not implemented for `NotZerocopy`
|
- = help: the trait `HasPadding<true>` is implemented for `AsBytes1`
-note: required by a bound in `assert_no_padding`
- --> tests/ui-stable/late_compile_pass.rs:27:10
- |
-27 | #[derive(AsBytes)]
- | ^^^^^^^ required by this bound in `assert_no_padding`
- = note: this error originates in the derive macro `AsBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
+ = help: the following other types implement trait `FromZeroes`:
+ ()
+ AU16
+ F32<O>
+ F64<O>
+ FromZeroes1
+ I128<O>
+ I16<O>
+ I32<O>
+ 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 `&'static str: FromBytes` is not satisfied
- --> tests/ui-stable/late_compile_pass.rs:18:10
+error[E0277]: the trait bound `NotZerocopy: FromBytes` is not satisfied
+ --> tests/ui-stable/late_compile_pass.rs:32:10
|
-18 | #[derive(FromBytes)]
- | ^^^^^^^^^ the trait `FromBytes` is not implemented for `&'static str`
+32 | #[derive(FromBytes)]
+ | ^^^^^^^^^ the trait `FromBytes` is not implemented for `NotZerocopy`
|
= help: the following other types implement trait `FromBytes`:
()
+ AU16
F32<O>
F64<O>
FromBytes1
I128<O>
I16<O>
I32<O>
- I64<O>
- and 36 others
-note: required by a bound in `ImplementsFromBytes`
- --> tests/ui-stable/late_compile_pass.rs:18:10
+ 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:32:10
|
-18 | #[derive(FromBytes)]
- | ^^^^^^^^^ required by this bound in `ImplementsFromBytes`
+32 | #[derive(FromBytes)]
+ | ^^^^^^^^^ the trait `FromZeroes` is not implemented for `FromBytes1`
+ |
+ = help: the following other types implement trait `FromZeroes`:
+ ()
+ AU16
+ F32<O>
+ F64<O>
+ FromZeroes1
+ I128<O>
+ I16<O>
+ I32<O>
+ 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 `u16: Unaligned` is not satisfied
- --> tests/ui-stable/late_compile_pass.rs:38:10
+error[E0277]: the trait bound `NotZerocopy: AsBytes` is not satisfied
+ --> tests/ui-stable/late_compile_pass.rs:41:10
|
-38 | #[derive(Unaligned)]
- | ^^^^^^^^^ the trait `Unaligned` is not implemented for `u16`
+41 | #[derive(AsBytes)]
+ | ^^^^^^^ the trait `AsBytes` is not implemented for `NotZerocopy`
|
- = help: the following other types implement trait `Unaligned`:
- i8
- u8
-note: required by a bound in `<Unaligned1 as Unaligned>::only_derive_is_allowed_to_implement_this_trait::ImplementsUnaligned`
- --> tests/ui-stable/late_compile_pass.rs:38:10
+ = help: the following other types implement trait `AsBytes`:
+ ()
+ AU16
+ AsBytes1
+ F32<O>
+ F64<O>
+ I128<O>
+ I16<O>
+ I32<O>
+ 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:51:10
+ |
+51 | #[derive(Unaligned)]
+ | ^^^^^^^^^ the trait `Unaligned` is not implemented for `AU16`
|
-38 | #[derive(Unaligned)]
- | ^^^^^^^^^ required by this bound in `<Unaligned1 as Unaligned>::only_derive_is_allowed_to_implement_this_trait::ImplementsUnaligned`
+ = help: the following other types implement trait `Unaligned`:
+ ()
+ F32<O>
+ F64<O>
+ I128<O>
+ I16<O>
+ I32<O>
+ I64<O>
+ ManuallyDrop<T>
+ 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 `u16: Unaligned` is not satisfied
- --> tests/ui-stable/late_compile_pass.rs:46:10
+error[E0277]: the trait bound `AU16: Unaligned` is not satisfied
+ --> tests/ui-stable/late_compile_pass.rs:59:10
|
-46 | #[derive(Unaligned)]
- | ^^^^^^^^^ the trait `Unaligned` is not implemented for `u16`
+59 | #[derive(Unaligned)]
+ | ^^^^^^^^^ the trait `Unaligned` is not implemented for `AU16`
|
= help: the following other types implement trait `Unaligned`:
- i8
- u8
-note: required by a bound in `<Unaligned2 as Unaligned>::only_derive_is_allowed_to_implement_this_trait::ImplementsUnaligned`
- --> tests/ui-stable/late_compile_pass.rs:46:10
- |
-46 | #[derive(Unaligned)]
- | ^^^^^^^^^ required by this bound in `<Unaligned2 as Unaligned>::only_derive_is_allowed_to_implement_this_trait::ImplementsUnaligned`
+ ()
+ F32<O>
+ F64<O>
+ I128<O>
+ I16<O>
+ I32<O>
+ I64<O>
+ ManuallyDrop<T>
+ 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 `u16: Unaligned` is not satisfied
- --> tests/ui-stable/late_compile_pass.rs:53:10
+error[E0277]: the trait bound `AU16: Unaligned` is not satisfied
+ --> tests/ui-stable/late_compile_pass.rs:66:10
|
-53 | #[derive(Unaligned)]
- | ^^^^^^^^^ the trait `Unaligned` is not implemented for `u16`
+66 | #[derive(Unaligned)]
+ | ^^^^^^^^^ the trait `Unaligned` is not implemented for `AU16`
|
= help: the following other types implement trait `Unaligned`:
- i8
- u8
-note: required by a bound in `<Unaligned3 as Unaligned>::only_derive_is_allowed_to_implement_this_trait::ImplementsUnaligned`
- --> tests/ui-stable/late_compile_pass.rs:53:10
- |
-53 | #[derive(Unaligned)]
- | ^^^^^^^^^ required by this bound in `<Unaligned3 as Unaligned>::only_derive_is_allowed_to_implement_this_trait::ImplementsUnaligned`
+ ()
+ F32<O>
+ F64<O>
+ I128<O>
+ I16<O>
+ I32<O>
+ I64<O>
+ ManuallyDrop<T>
+ 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)
diff --git a/tests/ui-stable/struct.rs b/tests/ui-stable/struct.rs
index ee8fd06..29aa0e8 100644
--- a/tests/ui-stable/struct.rs
+++ b/tests/ui-stable/struct.rs
@@ -5,6 +5,11 @@
#[macro_use]
extern crate zerocopy;
+#[path = "../util.rs"]
+mod util;
+
+use self::util::AU16;
+
fn main() {}
//
@@ -15,6 +20,13 @@ fn main() {}
#[repr(C)]
struct AsBytes1<T>(T);
+#[derive(AsBytes)]
+#[repr(C)]
+struct AsBytes2 {
+ foo: u8,
+ bar: AU16,
+}
+
//
// Unaligned errors
//
diff --git a/tests/ui-stable/struct.stderr b/tests/ui-stable/struct.stderr
index f3a5ccb..a82920e 100644
--- a/tests/ui-stable/struct.stderr
+++ b/tests/ui-stable/struct.stderr
@@ -1,49 +1,53 @@
-error: unsupported on types with type parameters
- --> tests/ui-stable/struct.rs:14:10
+error: unsupported on generic structs that are not repr(transparent) or repr(packed)
+ --> tests/ui-stable/struct.rs:19:10
|
-14 | #[derive(AsBytes)]
+19 | #[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:23:11
+ --> tests/ui-stable/struct.rs:35:11
|
-23 | #[repr(C, align(2))]
+35 | #[repr(C, align(2))]
| ^^^^^^^^
error: cannot derive Unaligned with repr(align(N > 1))
- --> tests/ui-stable/struct.rs:27:21
+ --> tests/ui-stable/struct.rs:39:21
|
-27 | #[repr(transparent, align(2))]
+39 | #[repr(transparent, align(2))]
| ^^^^^^^^
error: cannot derive Unaligned with repr(align(N > 1))
- --> tests/ui-stable/struct.rs:33:16
+ --> tests/ui-stable/struct.rs:45:16
|
-33 | #[repr(packed, align(2))]
+45 | #[repr(packed, align(2))]
| ^^^^^^^^
error: cannot derive Unaligned with repr(align(N > 1))
- --> tests/ui-stable/struct.rs:37:18
+ --> tests/ui-stable/struct.rs:49:18
|
-37 | #[repr(align(1), align(2))]
+49 | #[repr(align(1), align(2))]
| ^^^^^^^^
error: cannot derive Unaligned with repr(align(N > 1))
- --> tests/ui-stable/struct.rs:41:8
+ --> tests/ui-stable/struct.rs:53:8
|
-41 | #[repr(align(2), align(4))]
+53 | #[repr(align(2), align(4))]
| ^^^^^^^^
error[E0692]: transparent struct cannot have other repr hints
- --> tests/ui-stable/struct.rs:27:8
+ --> tests/ui-stable/struct.rs:39:8
|
-27 | #[repr(transparent, align(2))]
+39 | #[repr(transparent, align(2))]
| ^^^^^^^^^^^ ^^^^^^^^
-error[E0587]: type has conflicting packed and align representation hints
- --> tests/ui-stable/struct.rs:34:1
+error[E0277]: the trait bound `HasPadding<AsBytes2, true>: ShouldBe<false>` is not satisfied
+ --> tests/ui-stable/struct.rs:23:10
|
-34 | struct Unaligned3;
- | ^^^^^^^^^^^^^^^^^
+23 | #[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)
diff --git a/tests/ui-stable/union.rs b/tests/ui-stable/union.rs
index 0252cbe..e7761e0 100644
--- a/tests/ui-stable/union.rs
+++ b/tests/ui-stable/union.rs
@@ -5,6 +5,10 @@
#[macro_use]
extern crate zerocopy;
+#[path = "../util.rs"]
+mod util;
+
+use self::util::AU16;
use std::mem::ManuallyDrop;
fn main() {}
@@ -21,7 +25,7 @@ union AsBytes1<T> {
#[derive(AsBytes)]
#[repr(C)]
-union AsBytes {
+union AsBytes2 {
foo: u8,
bar: [u8; 2],
}
@@ -34,7 +38,7 @@ union AsBytes {
#[repr(C, align(2))]
union Unaligned1 {
foo: i16,
- bar: u16,
+ bar: AU16,
}
// Transparent unions are unstable; see issue #60405
diff --git a/tests/ui-stable/union.stderr b/tests/ui-stable/union.stderr
index 5726d99..6671271 100644
--- a/tests/ui-stable/union.stderr
+++ b/tests/ui-stable/union.stderr
@@ -1,51 +1,41 @@
error: unsupported on types with type parameters
- --> tests/ui-stable/union.rs:16:10
+ --> tests/ui-stable/union.rs:20:10
|
-16 | #[derive(AsBytes)]
+20 | #[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:34:11
+ --> tests/ui-stable/union.rs:38:11
|
-34 | #[repr(C, align(2))]
+38 | #[repr(C, align(2))]
| ^^^^^^^^
error: cannot derive Unaligned with repr(align(N > 1))
- --> tests/ui-stable/union.rs:50:16
+ --> tests/ui-stable/union.rs:54:16
|
-50 | #[repr(packed, align(2))]
+54 | #[repr(packed, align(2))]
| ^^^^^^^^
error: cannot derive Unaligned with repr(align(N > 1))
- --> tests/ui-stable/union.rs:56:18
+ --> tests/ui-stable/union.rs:60:18
|
-56 | #[repr(align(1), align(2))]
+60 | #[repr(align(1), align(2))]
| ^^^^^^^^
error: cannot derive Unaligned with repr(align(N > 1))
- --> tests/ui-stable/union.rs:62:8
+ --> tests/ui-stable/union.rs:66:8
|
-62 | #[repr(align(2), align(4))]
+66 | #[repr(align(2), align(4))]
| ^^^^^^^^
-error[E0277]: the trait bound `AsBytes: FieldsAreSameSize<true>` is not satisfied
- --> tests/ui-stable/union.rs:22:10
+error[E0277]: the trait bound `HasPadding<AsBytes2, true>: ShouldBe<false>` is not satisfied
+ --> tests/ui-stable/union.rs:26:10
|
-22 | #[derive(AsBytes)]
- | ^^^^^^^ the trait `FieldsAreSameSize<true>` is not implemented for `AsBytes`
+26 | #[derive(AsBytes)]
+ | ^^^^^^^ the trait `ShouldBe<false>` is not implemented for `HasPadding<AsBytes2, true>`
|
- = help: the trait `FieldsAreSameSize<false>` is implemented for `AsBytes`
-note: required by a bound in `assert_fields_are_same_size`
- --> tests/ui-stable/union.rs:22:10
- |
-22 | #[derive(AsBytes)]
- | ^^^^^^^ required by this bound in `assert_fields_are_same_size`
+ = 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[E0587]: type has conflicting packed and align representation hints
- --> tests/ui-stable/union.rs:51:1
- |
-51 | union Unaligned3 {
- | ^^^^^^^^^^^^^^^^
diff --git a/tests/ui/late_compile_pass.stderr b/tests/ui/late_compile_pass.stderr
deleted file mode 100644
index ce5d9b5..0000000
--- a/tests/ui/late_compile_pass.stderr
+++ /dev/null
@@ -1,84 +0,0 @@
-error[E0277]: the trait bound `AsBytes1: HasPadding<false>` is not satisfied
- --> tests/ui/late_compile_pass.rs:29:8
- |
-29 | struct AsBytes1 {
- | ^^^^^^^^ the trait `HasPadding<false>` is not implemented for `AsBytes1`
- |
- = help: the trait `HasPadding<true>` is implemented for `AsBytes1`
-note: required by a bound in `assert_no_padding`
- --> tests/ui/late_compile_pass.rs:27:10
- |
-27 | #[derive(AsBytes)]
- | ^^^^^^^ required by this bound in `assert_no_padding`
- = 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 `&'static str: FromBytes` is not satisfied
- --> tests/ui/late_compile_pass.rs:18:10
- |
-18 | #[derive(FromBytes)]
- | ^^^^^^^^^ the trait `FromBytes` is not implemented for `&'static str`
- |
- = help: the following other types implement trait `FromBytes`:
- ()
- F32<O>
- F64<O>
- FromBytes1
- I128<O>
- I16<O>
- I32<O>
- I64<O>
- and 36 others
-note: required by a bound in `ImplementsFromBytes`
- --> tests/ui/late_compile_pass.rs:18:10
- |
-18 | #[derive(FromBytes)]
- | ^^^^^^^^^ required by this bound in `ImplementsFromBytes`
- = 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 `u16: Unaligned` is not satisfied
- --> tests/ui/late_compile_pass.rs:38:10
- |
-38 | #[derive(Unaligned)]
- | ^^^^^^^^^ the trait `Unaligned` is not implemented for `u16`
- |
- = help: the following other types implement trait `Unaligned`:
- i8
- u8
-note: required by a bound in `<Unaligned1 as Unaligned>::only_derive_is_allowed_to_implement_this_trait::ImplementsUnaligned`
- --> tests/ui/late_compile_pass.rs:38:10
- |
-38 | #[derive(Unaligned)]
- | ^^^^^^^^^ required by this bound in `<Unaligned1 as Unaligned>::only_derive_is_allowed_to_implement_this_trait::ImplementsUnaligned`
- = 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 `u16: Unaligned` is not satisfied
- --> tests/ui/late_compile_pass.rs:46:10
- |
-46 | #[derive(Unaligned)]
- | ^^^^^^^^^ the trait `Unaligned` is not implemented for `u16`
- |
- = help: the following other types implement trait `Unaligned`:
- i8
- u8
-note: required by a bound in `<Unaligned2 as Unaligned>::only_derive_is_allowed_to_implement_this_trait::ImplementsUnaligned`
- --> tests/ui/late_compile_pass.rs:46:10
- |
-46 | #[derive(Unaligned)]
- | ^^^^^^^^^ required by this bound in `<Unaligned2 as Unaligned>::only_derive_is_allowed_to_implement_this_trait::ImplementsUnaligned`
- = 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 `u16: Unaligned` is not satisfied
- --> tests/ui/late_compile_pass.rs:53:10
- |
-53 | #[derive(Unaligned)]
- | ^^^^^^^^^ the trait `Unaligned` is not implemented for `u16`
- |
- = help: the following other types implement trait `Unaligned`:
- i8
- u8
-note: required by a bound in `<Unaligned3 as Unaligned>::only_derive_is_allowed_to_implement_this_trait::ImplementsUnaligned`
- --> tests/ui/late_compile_pass.rs:53:10
- |
-53 | #[derive(Unaligned)]
- | ^^^^^^^^^ required by this bound in `<Unaligned3 as Unaligned>::only_derive_is_allowed_to_implement_this_trait::ImplementsUnaligned`
- = note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/tests/ui/struct.stderr b/tests/ui/struct.stderr
deleted file mode 100644
index b35739e..0000000
--- a/tests/ui/struct.stderr
+++ /dev/null
@@ -1,49 +0,0 @@
-error: unsupported on types with type parameters
- --> tests/ui/struct.rs:14:10
- |
-14 | #[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/struct.rs:23:11
- |
-23 | #[repr(C, align(2))]
- | ^^^^^^^^
-
-error: cannot derive Unaligned with repr(align(N > 1))
- --> tests/ui/struct.rs:27:21
- |
-27 | #[repr(transparent, align(2))]
- | ^^^^^^^^
-
-error: cannot derive Unaligned with repr(align(N > 1))
- --> tests/ui/struct.rs:33:16
- |
-33 | #[repr(packed, align(2))]
- | ^^^^^^^^
-
-error: cannot derive Unaligned with repr(align(N > 1))
- --> tests/ui/struct.rs:37:18
- |
-37 | #[repr(align(1), align(2))]
- | ^^^^^^^^
-
-error: cannot derive Unaligned with repr(align(N > 1))
- --> tests/ui/struct.rs:41:8
- |
-41 | #[repr(align(2), align(4))]
- | ^^^^^^^^
-
-error[E0692]: transparent struct cannot have other repr hints
- --> tests/ui/struct.rs:27:8
- |
-27 | #[repr(transparent, align(2))]
- | ^^^^^^^^^^^ ^^^^^^^^
-
-error[E0587]: type has conflicting packed and align representation hints
- --> tests/ui/struct.rs:34:1
- |
-34 | struct Unaligned3;
- | ^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/union.stderr b/tests/ui/union.stderr
deleted file mode 100644
index 4575639..0000000
--- a/tests/ui/union.stderr
+++ /dev/null
@@ -1,51 +0,0 @@
-error: unsupported on types with type parameters
- --> tests/ui/union.rs:16:10
- |
-16 | #[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/union.rs:34:11
- |
-34 | #[repr(C, align(2))]
- | ^^^^^^^^
-
-error: cannot derive Unaligned with repr(align(N > 1))
- --> tests/ui/union.rs:50:16
- |
-50 | #[repr(packed, align(2))]
- | ^^^^^^^^
-
-error: cannot derive Unaligned with repr(align(N > 1))
- --> tests/ui/union.rs:56:18
- |
-56 | #[repr(align(1), align(2))]
- | ^^^^^^^^
-
-error: cannot derive Unaligned with repr(align(N > 1))
- --> tests/ui/union.rs:62:8
- |
-62 | #[repr(align(2), align(4))]
- | ^^^^^^^^
-
-error[E0277]: the trait bound `AsBytes: FieldsAreSameSize<true>` is not satisfied
- --> tests/ui/union.rs:24:7
- |
-24 | union AsBytes {
- | ^^^^^^^ the trait `FieldsAreSameSize<true>` is not implemented for `AsBytes`
- |
- = help: the trait `FieldsAreSameSize<false>` is implemented for `AsBytes`
-note: required by a bound in `assert_fields_are_same_size`
- --> tests/ui/union.rs:22:10
- |
-22 | #[derive(AsBytes)]
- | ^^^^^^^ required by this bound in `assert_fields_are_same_size`
- = 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/union.rs:51:1
- |
-51 | union Unaligned3 {
- | ^^^^^^^^^^^^^^^^
diff --git a/tests/union_as_bytes.rs b/tests/union_as_bytes.rs
index fd848cc..62b8827 100644
--- a/tests/union_as_bytes.rs
+++ b/tests/union_as_bytes.rs
@@ -6,18 +6,7 @@
use std::{marker::PhantomData, option::IntoIter};
-use zerocopy::AsBytes;
-
-struct IsAsBytes<T: AsBytes>(T);
-
-// Fail compilation if `$ty: !AsBytes`.
-macro_rules! is_as_bytes {
- ($ty:ty) => {
- const _: () = {
- let _: IsAsBytes<$ty>;
- };
- };
-}
+use {static_assertions::assert_impl_all, zerocopy::AsBytes};
// A union is `AsBytes` if:
// - all fields are `AsBytes`
@@ -31,7 +20,7 @@ union CZst {
a: (),
}
-is_as_bytes!(CZst);
+assert_impl_all!(CZst: AsBytes);
#[derive(AsBytes)]
#[repr(C)]
@@ -40,7 +29,7 @@ union C {
b: u8,
}
-is_as_bytes!(C);
+assert_impl_all!(C: AsBytes);
// Transparent unions are unstable; see issue #60405
// <https://github.com/rust-lang/rust/issues/60405> for more information.
@@ -60,7 +49,7 @@ union CZstPacked {
a: (),
}
-is_as_bytes!(CZstPacked);
+assert_impl_all!(CZstPacked: AsBytes);
#[derive(AsBytes)]
#[repr(C, packed)]
@@ -69,7 +58,7 @@ union CPacked {
b: i8,
}
-is_as_bytes!(CPacked);
+assert_impl_all!(CPacked: AsBytes);
#[derive(AsBytes)]
#[repr(C, packed)]
@@ -79,4 +68,4 @@ union CMultibytePacked {
c: f32,
}
-is_as_bytes!(CMultibytePacked);
+assert_impl_all!(CMultibytePacked: AsBytes);
diff --git a/tests/union_from_bytes.rs b/tests/union_from_bytes.rs
index ef6d403..dae2491 100644
--- a/tests/union_from_bytes.rs
+++ b/tests/union_from_bytes.rs
@@ -6,45 +6,37 @@
use std::{marker::PhantomData, option::IntoIter};
-use zerocopy::FromBytes;
-
-struct IsFromBytes<T: FromBytes>(T);
-
-// Fail compilation if `$ty: !FromBytes`.
-macro_rules! is_from_bytes {
- ($ty:ty) => {
- const _: () = {
- let _: IsFromBytes<$ty>;
- };
- };
-}
+use {
+ static_assertions::assert_impl_all,
+ zerocopy::{FromBytes, FromZeroes},
+};
// A union is `FromBytes` if:
// - all fields are `FromBytes`
-#[derive(Clone, Copy, FromBytes)]
+#[derive(Clone, Copy, FromZeroes, FromBytes)]
union Zst {
a: (),
}
-is_from_bytes!(Zst);
+assert_impl_all!(Zst: FromBytes);
-#[derive(FromBytes)]
+#[derive(FromZeroes, FromBytes)]
union One {
a: u8,
}
-is_from_bytes!(One);
+assert_impl_all!(One: FromBytes);
-#[derive(FromBytes)]
+#[derive(FromZeroes, FromBytes)]
union Two {
a: u8,
b: Zst,
}
-is_from_bytes!(Two);
+assert_impl_all!(Two: FromBytes);
-#[derive(FromBytes)]
+#[derive(FromZeroes, FromBytes)]
union TypeParams<'a, T: Copy, I: Iterator>
where
I::Item: Copy,
@@ -57,4 +49,4 @@ where
g: PhantomData<String>,
}
-is_from_bytes!(TypeParams<'static, (), IntoIter<()>>);
+assert_impl_all!(TypeParams<'static, (), IntoIter<()>>: FromBytes);
diff --git a/tests/union_from_zeroes.rs b/tests/union_from_zeroes.rs
new file mode 100644
index 0000000..b5822de
--- /dev/null
+++ b/tests/union_from_zeroes.rs
@@ -0,0 +1,52 @@
+// 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::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);
diff --git a/tests/union_unaligned.rs b/tests/union_unaligned.rs
index 076595c..9ccfe93 100644
--- a/tests/union_unaligned.rs
+++ b/tests/union_unaligned.rs
@@ -6,18 +6,7 @@
use std::{marker::PhantomData, option::IntoIter};
-use zerocopy::Unaligned;
-
-struct IsUnaligned<T: Unaligned>(T);
-
-// Fail compilation if `$ty: !Unaligned`.
-macro_rules! is_unaligned {
- ($ty:ty) => {
- const _: () = {
- let _: IsUnaligned<$ty>;
- };
- };
-}
+use {static_assertions::assert_impl_all, zerocopy::Unaligned};
// A union is `Unaligned` if:
// - `repr(align)` is no more than 1 and either
@@ -31,7 +20,7 @@ union Foo {
a: u8,
}
-is_unaligned!(Foo);
+assert_impl_all!(Foo: Unaligned);
// Transparent unions are unstable; see issue #60405
// <https://github.com/rust-lang/rust/issues/60405> for more information.
@@ -47,10 +36,17 @@ is_unaligned!(Foo);
#[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,
}
-is_unaligned!(Baz);
+assert_impl_all!(Baz: Unaligned);
#[derive(Unaligned)]
#[repr(C, align(1))]
@@ -58,7 +54,7 @@ union FooAlign {
a: u8,
}
-is_unaligned!(FooAlign);
+assert_impl_all!(FooAlign: Unaligned);
#[derive(Unaligned)]
#[repr(C)]
@@ -74,4 +70,4 @@ where
g: PhantomData<String>,
}
-is_unaligned!(TypeParams<'static, (), IntoIter<()>>);
+assert_impl_all!(TypeParams<'static, (), IntoIter<()>>: Unaligned);
diff --git a/tests/util.rs b/tests/util.rs
new file mode 100644
index 0000000..7615d84
--- /dev/null
+++ b/tests/util.rs
@@ -0,0 +1,16 @@
+// 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.
+
+use zerocopy::{AsBytes, FromBytes, FromZeroes};
+
+/// A type that doesn't implement any zerocopy traits.
+pub struct NotZerocopy(());
+
+/// 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(FromZeroes, FromBytes, AsBytes, Copy, Clone)]
+#[repr(C, align(2))]
+pub struct AU16(u16);