Vendor dependencies for 0.3.0 release

This commit is contained in:
2025-09-27 10:29:08 -05:00
parent 0c8d39d483
commit 82ab7f317b
26803 changed files with 16134934 additions and 0 deletions

File diff suppressed because one or more lines are too long

266
vendor/zerocopy-derive/Cargo.lock generated vendored Normal file
View File

@@ -0,0 +1,266 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "basic-toml"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba62675e8242a4c4e806d12f11d136e626e6c8361d6b829310732241652a178a"
dependencies = [
"serde",
]
[[package]]
name = "dissimilar"
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8975ffdaa0ef3661bfe02dbdcc06c9f829dfafe6a3c474de366a8d5e44276921"
[[package]]
name = "glob"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2"
[[package]]
name = "itoa"
version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
[[package]]
name = "libc"
version = "0.2.163"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fdaeca4cf44ed4ac623e86ef41f056e848dbeab7ec043ecb7326ba300b36fd0"
[[package]]
name = "memchr"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]]
name = "once_cell"
version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5"
[[package]]
name = "prettyplease"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d3928fb5db768cb86f891ff014f0144589297e3c6a1aba6ed7cecfdace270c7"
dependencies = [
"proc-macro2",
"syn",
]
[[package]]
name = "proc-macro2"
version = "1.0.101"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rustversion"
version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
[[package]]
name = "ryu"
version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
[[package]]
name = "serde"
version = "1.0.219"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.219"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.143"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d401abef1d108fbd9cbaebc3e46611f4b1021f714a0597a71f41ee463f5f4a5a"
dependencies = [
"itoa",
"memchr",
"ryu",
"serde",
]
[[package]]
name = "static_assertions"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]]
name = "syn"
version = "2.0.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "termcolor"
version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755"
dependencies = [
"winapi-util",
]
[[package]]
name = "trybuild"
version = "1.0.89"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a9d3ba662913483d6722303f619e75ea10b7855b0f8e0d72799cf8621bb488f"
dependencies = [
"basic-toml",
"dissimilar",
"glob",
"once_cell",
"serde",
"serde_derive",
"serde_json",
"termcolor",
]
[[package]]
name = "unicode-ident"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
[[package]]
name = "winapi-util"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b"
dependencies = [
"windows-sys",
]
[[package]]
name = "windows-sys"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-targets"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_gnullvm",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_i686_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "zerocopy-derive"
version = "0.8.27"
dependencies = [
"dissimilar",
"libc",
"once_cell",
"prettyplease",
"proc-macro2",
"quote",
"rustversion",
"static_assertions",
"syn",
"trybuild",
]

200
vendor/zerocopy-derive/Cargo.toml vendored Normal file
View File

@@ -0,0 +1,200 @@
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
#
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
# to registry (e.g., crates.io) dependencies.
#
# If you are reading this file be aware that the original Cargo.toml
# will likely look very different (and much more reasonable).
# See Cargo.toml.orig for the original contents.
[package]
edition = "2021"
name = "zerocopy-derive"
version = "0.8.27"
authors = [
"Joshua Liebow-Feeser <joshlf@google.com>",
"Jack Wrenn <jswrenn@amazon.com>",
]
build = false
exclude = [
".*",
"tests/enum_from_bytes.rs",
"tests/ui-nightly/enum_from_bytes_u16_too_few.rs.disabled",
]
autolib = false
autobins = false
autoexamples = false
autotests = false
autobenches = false
description = "Custom derive for traits from the zerocopy crate"
readme = false
license = "BSD-2-Clause OR Apache-2.0 OR MIT"
repository = "https://github.com/google/zerocopy"
[lib]
name = "zerocopy_derive"
path = "src/lib.rs"
proc-macro = true
[[test]]
name = "crate_path"
path = "tests/crate_path.rs"
[[test]]
name = "deprecated"
path = "tests/deprecated.rs"
[[test]]
name = "enum_from_zeros"
path = "tests/enum_from_zeros.rs"
[[test]]
name = "enum_known_layout"
path = "tests/enum_known_layout.rs"
[[test]]
name = "enum_no_cell"
path = "tests/enum_no_cell.rs"
[[test]]
name = "enum_to_bytes"
path = "tests/enum_to_bytes.rs"
[[test]]
name = "enum_try_from_bytes"
path = "tests/enum_try_from_bytes.rs"
[[test]]
name = "enum_unaligned"
path = "tests/enum_unaligned.rs"
[[test]]
name = "eq"
path = "tests/eq.rs"
[[test]]
name = "hash"
path = "tests/hash.rs"
[[test]]
name = "hygiene"
path = "tests/hygiene.rs"
[[test]]
name = "include"
path = "tests/include.rs"
[[test]]
name = "issue_2117"
path = "tests/issue_2117.rs"
[[test]]
name = "paths_and_modules"
path = "tests/paths_and_modules.rs"
[[test]]
name = "priv_in_pub"
path = "tests/priv_in_pub.rs"
[[test]]
name = "struct_from_bytes"
path = "tests/struct_from_bytes.rs"
[[test]]
name = "struct_from_zeros"
path = "tests/struct_from_zeros.rs"
[[test]]
name = "struct_known_layout"
path = "tests/struct_known_layout.rs"
[[test]]
name = "struct_no_cell"
path = "tests/struct_no_cell.rs"
[[test]]
name = "struct_to_bytes"
path = "tests/struct_to_bytes.rs"
[[test]]
name = "struct_try_from_bytes"
path = "tests/struct_try_from_bytes.rs"
[[test]]
name = "struct_unaligned"
path = "tests/struct_unaligned.rs"
[[test]]
name = "trybuild"
path = "tests/trybuild.rs"
[[test]]
name = "union_from_bytes"
path = "tests/union_from_bytes.rs"
[[test]]
name = "union_from_zeros"
path = "tests/union_from_zeros.rs"
[[test]]
name = "union_known_layout"
path = "tests/union_known_layout.rs"
[[test]]
name = "union_no_cell"
path = "tests/union_no_cell.rs"
[[test]]
name = "union_to_bytes"
path = "tests/union_to_bytes.rs"
[[test]]
name = "union_try_from_bytes"
path = "tests/union_try_from_bytes.rs"
[[test]]
name = "union_unaligned"
path = "tests/union_unaligned.rs"
[[test]]
name = "unsafe_cell"
path = "tests/unsafe_cell.rs"
[dependencies.proc-macro2]
version = "1.0.1"
[dependencies.quote]
version = "1.0.10"
[dependencies.syn]
version = "2.0.46"
features = ["full"]
[dev-dependencies.dissimilar]
version = "1.0.9"
[dev-dependencies.libc]
version = "=0.2.163"
[dev-dependencies.once_cell]
version = "=1.9"
[dev-dependencies.prettyplease]
version = "=0.2.17"
[dev-dependencies.rustversion]
version = "1.0"
[dev-dependencies.static_assertions]
version = "1.1"
[dev-dependencies.trybuild]
version = "=1.0.89"
features = ["diff"]
[lints.rust.unexpected_cfgs]
level = "warn"
priority = 0
check-cfg = ["cfg(zerocopy_derive_union_into_bytes)"]

202
vendor/zerocopy-derive/LICENSE-APACHE vendored Normal file
View File

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

24
vendor/zerocopy-derive/LICENSE-BSD vendored Normal file
View File

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

26
vendor/zerocopy-derive/LICENSE-MIT vendored Normal file
View File

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

386
vendor/zerocopy-derive/src/enum.rs vendored Normal file
View File

@@ -0,0 +1,386 @@
// Copyright 2024 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.
use proc_macro2::{Span, TokenStream};
use quote::quote;
use syn::{parse_quote, DataEnum, Error, Fields, Generics, Ident, Path};
use crate::{derive_try_from_bytes_inner, repr::EnumRepr, Trait};
/// Generates a tag enum for the given enum. This generates an enum with the
/// same non-align `repr`s, variants, and corresponding discriminants, but none
/// of the fields.
pub(crate) fn generate_tag_enum(repr: &EnumRepr, data: &DataEnum) -> TokenStream {
let variants = data.variants.iter().map(|v| {
let ident = &v.ident;
if let Some((eq, discriminant)) = &v.discriminant {
quote! { #ident #eq #discriminant }
} else {
quote! { #ident }
}
});
// Don't include any `repr(align)` when generating the tag enum, as that
// could add padding after the tag but before any variants, which is not the
// correct behavior.
let repr = match repr {
EnumRepr::Transparent(span) => quote::quote_spanned! { *span => #[repr(transparent)] },
EnumRepr::Compound(c, _) => quote! { #c },
};
quote! {
#repr
#[allow(dead_code, non_camel_case_types)]
enum ___ZerocopyTag {
#(#variants,)*
}
}
}
fn tag_ident(variant_ident: &Ident) -> Ident {
Ident::new(&format!("___ZEROCOPY_TAG_{}", variant_ident), variant_ident.span())
}
/// Generates a constant for the tag associated with each variant of the enum.
/// When we match on the enum's tag, each arm matches one of these constants. We
/// have to use constants here because:
///
/// - The type that we're matching on is not the type of the tag, it's an
/// integer of the same size as the tag type and with the same bit patterns.
/// - We can't read the enum tag as an enum because the bytes may not represent
/// a valid variant.
/// - Patterns do not currently support const expressions, so we have to assign
/// these constants to names rather than use them inline in the `match`
/// statement.
fn generate_tag_consts(data: &DataEnum) -> TokenStream {
let tags = data.variants.iter().map(|v| {
let variant_ident = &v.ident;
let tag_ident = tag_ident(variant_ident);
quote! {
// This casts the enum variant to its discriminant, and then
// converts the discriminant to the target integral type via a
// numeric cast [1].
//
// Because these are the same size, this is defined to be a no-op
// and therefore is a lossless conversion [2].
//
// [1]: https://doc.rust-lang.org/stable/reference/expressions/operator-expr.html#enum-cast
// [2]: https://doc.rust-lang.org/stable/reference/expressions/operator-expr.html#numeric-cast
#[allow(non_upper_case_globals)]
const #tag_ident: ___ZerocopyTagPrimitive =
___ZerocopyTag::#variant_ident as ___ZerocopyTagPrimitive;
}
});
quote! {
#(#tags)*
}
}
fn variant_struct_ident(variant_ident: &Ident) -> Ident {
Ident::new(&format!("___ZerocopyVariantStruct_{}", variant_ident), variant_ident.span())
}
/// Generates variant structs for the given enum variant.
///
/// These are structs associated with each variant of an enum. They are
/// `repr(C)` tuple structs with the same fields as the variant after a
/// `MaybeUninit<___ZerocopyInnerTag>`.
///
/// In order to unify the generated types for `repr(C)` and `repr(int)` enums,
/// we use a "fused" representation with fields for both an inner tag and an
/// outer tag. Depending on the repr, we will set one of these tags to the tag
/// type and the other to `()`. This lets us generate the same code but put the
/// tags in different locations.
fn generate_variant_structs(
enum_name: &Ident,
generics: &Generics,
data: &DataEnum,
zerocopy_crate: &Path,
) -> TokenStream {
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
// All variant structs have a `PhantomData<MyEnum<...>>` field because we
// don't know which generic parameters each variant will use, and unused
// generic parameters are a compile error.
let phantom_ty = quote! {
core_reexport::marker::PhantomData<#enum_name #ty_generics>
};
let variant_structs = data.variants.iter().filter_map(|variant| {
// We don't generate variant structs for unit variants because we only
// need to check the tag. This helps cut down our generated code a bit.
if matches!(variant.fields, Fields::Unit) {
return None;
}
let variant_struct_ident = variant_struct_ident(&variant.ident);
let field_types = variant.fields.iter().map(|f| &f.ty);
let variant_struct = parse_quote! {
#[repr(C)]
#[allow(non_snake_case)]
struct #variant_struct_ident #impl_generics (
core_reexport::mem::MaybeUninit<___ZerocopyInnerTag>,
#(#field_types,)*
#phantom_ty,
) #where_clause;
};
// We do this rather than emitting `#[derive(::zerocopy::TryFromBytes)]`
// because that is not hygienic, and this is also more performant.
let try_from_bytes_impl =
derive_try_from_bytes_inner(&variant_struct, Trait::TryFromBytes, zerocopy_crate)
.expect("derive_try_from_bytes_inner should not fail on synthesized type");
Some(quote! {
#variant_struct
#try_from_bytes_impl
})
});
quote! {
#(#variant_structs)*
}
}
fn generate_variants_union(generics: &Generics, data: &DataEnum) -> TokenStream {
let (_, ty_generics, _) = generics.split_for_impl();
let fields = data.variants.iter().filter_map(|variant| {
// We don't generate variant structs for unit variants because we only
// need to check the tag. This helps cut down our generated code a bit.
if matches!(variant.fields, Fields::Unit) {
return None;
}
// Field names are prefixed with `__field_` to prevent name collision with
// the `__nonempty` field.
let field_name = Ident::new(&format!("__field_{}", &variant.ident), variant.ident.span());
let variant_struct_ident = variant_struct_ident(&variant.ident);
Some(quote! {
#field_name: core_reexport::mem::ManuallyDrop<
#variant_struct_ident #ty_generics
>,
})
});
quote! {
#[repr(C)]
#[allow(non_snake_case)]
union ___ZerocopyVariants #generics {
#(#fields)*
// Enums can have variants with no fields, but unions must
// have at least one field. So we just add a trailing unit
// to ensure that this union always has at least one field.
// Because this union is `repr(C)`, this unit type does not
// affect the layout.
__nonempty: (),
}
}
}
/// Generates an implementation of `is_bit_valid` for an arbitrary enum.
///
/// The general process is:
///
/// 1. Generate a tag enum. This is an enum with the same repr, variants, and
/// corresponding discriminants as the original enum, but without any fields
/// on the variants. This gives us access to an enum where the variants have
/// the same discriminants as the one we're writing `is_bit_valid` for.
/// 2. Make constants from the variants of the tag enum. We need these because
/// we can't put const exprs in match arms.
/// 3. Generate variant structs. These are structs which have the same fields as
/// each variant of the enum, and are `#[repr(C)]` with an optional "inner
/// tag".
/// 4. Generate a variants union, with one field for each variant struct type.
/// 5. And finally, our raw enum is a `#[repr(C)]` struct of an "outer tag" and
/// the variants union.
///
/// See these reference links for fully-worked example decompositions.
///
/// - `repr(C)`: <https://doc.rust-lang.org/reference/type-layout.html#reprc-enums-with-fields>
/// - `repr(int)`: <https://doc.rust-lang.org/reference/type-layout.html#primitive-representation-of-enums-with-fields>
/// - `repr(C, int)`: <https://doc.rust-lang.org/reference/type-layout.html#combining-primitive-representations-of-enums-with-fields-and-reprc>
pub(crate) fn derive_is_bit_valid(
enum_ident: &Ident,
repr: &EnumRepr,
generics: &Generics,
data: &DataEnum,
zerocopy_crate: &Path,
) -> Result<TokenStream, Error> {
let trait_path = Trait::TryFromBytes.crate_path(zerocopy_crate);
let tag_enum = generate_tag_enum(repr, data);
let tag_consts = generate_tag_consts(data);
let (outer_tag_type, inner_tag_type) = if repr.is_c() {
(quote! { ___ZerocopyTag }, quote! { () })
} else if repr.is_primitive() {
(quote! { () }, quote! { ___ZerocopyTag })
} else {
return Err(Error::new(
Span::call_site(),
"must have #[repr(C)] or #[repr(Int)] attribute in order to guarantee this type's memory layout",
));
};
let variant_structs = generate_variant_structs(enum_ident, generics, data, zerocopy_crate);
let variants_union = generate_variants_union(generics, data);
let (_, ty_generics, _) = generics.split_for_impl();
let match_arms = data.variants.iter().map(|variant| {
let tag_ident = tag_ident(&variant.ident);
let variant_struct_ident = variant_struct_ident(&variant.ident);
if matches!(variant.fields, Fields::Unit) {
// Unit variants don't need any further validation beyond checking
// the tag.
quote! {
#tag_ident => true
}
} else {
quote! {
#tag_ident => {
// SAFETY:
// - This cast is from a `repr(C)` union which has a field
// of type `variant_struct_ident` to that variant struct
// type itself. This addresses a subset of the bytes
// addressed by `variants`.
// - The returned pointer is cast from `p`, and so has the
// same provenance as `p`.
// - We checked that the tag of the enum matched the
// constant for this variant, so this cast preserves
// types and locations of all fields. Therefore, any
// `UnsafeCell`s will have the same location as in the
// original type.
let variant = unsafe {
variants.cast_unsized_unchecked(
|p: #zerocopy_crate::pointer::PtrInner<'_, ___ZerocopyVariants #ty_generics>| {
p.cast_sized::<#variant_struct_ident #ty_generics>()
}
)
};
// SAFETY: `cast_unsized_unchecked` removes the
// initialization invariant from `p`, so we re-assert that
// all of the bytes are initialized.
let variant = unsafe { variant.assume_initialized() };
<
#variant_struct_ident #ty_generics as #trait_path
>::is_bit_valid(variant)
}
}
}
});
Ok(quote! {
// SAFETY: We use `is_bit_valid` to validate that the bit pattern of the
// enum's tag corresponds to one of the enum's discriminants. Then, we
// check the bit validity of each field of the corresponding variant.
// Thus, this is a sound implementation of `is_bit_valid`.
fn is_bit_valid<___ZerocopyAliasing>(
mut candidate: #zerocopy_crate::Maybe<'_, Self, ___ZerocopyAliasing>,
) -> #zerocopy_crate::util::macro_util::core_reexport::primitive::bool
where
___ZerocopyAliasing: #zerocopy_crate::pointer::invariant::Reference,
{
use #zerocopy_crate::util::macro_util::core_reexport;
#tag_enum
type ___ZerocopyTagPrimitive = #zerocopy_crate::util::macro_util::SizeToTag<
{ core_reexport::mem::size_of::<___ZerocopyTag>() },
>;
#tag_consts
type ___ZerocopyOuterTag = #outer_tag_type;
type ___ZerocopyInnerTag = #inner_tag_type;
#variant_structs
#variants_union
#[repr(C)]
struct ___ZerocopyRawEnum #generics {
tag: ___ZerocopyOuterTag,
variants: ___ZerocopyVariants #ty_generics,
}
let tag = {
// SAFETY:
// - The provided cast addresses a subset of the bytes addressed
// by `candidate` because it addresses the starting tag of the
// enum.
// - Because the pointer is cast from `candidate`, it has the
// same provenance as it.
// - There are no `UnsafeCell`s in the tag because it is a
// primitive integer.
let tag_ptr = unsafe {
candidate.reborrow().cast_unsized_unchecked(|p: #zerocopy_crate::pointer::PtrInner<'_, Self>| {
p.cast_sized::<___ZerocopyTagPrimitive>()
})
};
// SAFETY: `tag_ptr` is casted from `candidate`, whose referent
// is `Initialized`. Since we have not written uninitialized
// bytes into the referent, `tag_ptr` is also `Initialized`.
let tag_ptr = unsafe { tag_ptr.assume_initialized() };
tag_ptr.recall_validity::<_, (_, (_, _))>().read_unaligned::<#zerocopy_crate::BecauseImmutable>()
};
// SAFETY:
// - The raw enum has the same fields in the same locations as the
// input enum, and may have a lower alignment. This guarantees
// that it addresses a subset of the bytes addressed by
// `candidate`.
// - The returned pointer is cast from `p`, and so has the same
// provenance as `p`.
// - The raw enum has the same types at the same locations as the
// original enum, and so preserves the locations of any
// `UnsafeCell`s.
let raw_enum = unsafe {
candidate.cast_unsized_unchecked(|p: #zerocopy_crate::pointer::PtrInner<'_, Self>| {
p.cast_sized::<___ZerocopyRawEnum #ty_generics>()
})
};
// SAFETY: `cast_unsized_unchecked` removes the initialization
// invariant from `p`, so we re-assert that all of the bytes are
// initialized.
let raw_enum = unsafe { raw_enum.assume_initialized() };
// SAFETY:
// - This projection returns a subfield of `this` using
// `addr_of_mut!`.
// - Because the subfield pointer is derived from `this`, it has the
// same provenance.
// - The locations of `UnsafeCell`s in the subfield match the
// locations of `UnsafeCell`s in `this`. This is because the
// subfield pointer just points to a smaller portion of the
// overall struct.
let variants = unsafe {
use #zerocopy_crate::pointer::PtrInner;
raw_enum.cast_unsized_unchecked(|p: PtrInner<'_, ___ZerocopyRawEnum #ty_generics>| {
let p = p.as_non_null().as_ptr();
let ptr = core_reexport::ptr::addr_of_mut!((*p).variants);
// SAFETY: `ptr` is a projection into `p`, which is
// `NonNull`, and guaranteed not to wrap around the address
// space. Thus, `ptr` cannot be null.
let ptr = unsafe { core_reexport::ptr::NonNull::new_unchecked(ptr) };
unsafe { PtrInner::new(ptr) }
})
};
#[allow(non_upper_case_globals)]
match tag {
#(#match_arms,)*
_ => false,
}
}
})
}

114
vendor/zerocopy-derive/src/ext.rs vendored Normal file
View File

@@ -0,0 +1,114 @@
// Copyright 2019 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.
use proc_macro2::{Span, TokenStream};
use quote::ToTokens;
use syn::{Data, DataEnum, DataStruct, DataUnion, Field, Ident, Index, Type, Visibility};
pub(crate) trait DataExt {
/// Extracts the names and types of all fields. For enums, extracts the
/// names and types of fields from each variant. For tuple structs, the
/// names are the indices used to index into the struct (ie, `0`, `1`, etc).
///
/// FIXME: Extracting field names for enums doesn't really make sense. Types
/// makes sense because we don't care about where they live - we just care
/// about transitive ownership. But for field names, we'd only use them when
/// generating is_bit_valid, which cares about where they live.
fn fields(&self) -> Vec<(&Visibility, TokenStream, &Type)>;
fn variants(&self) -> Vec<Vec<(&Visibility, TokenStream, &Type)>>;
fn tag(&self) -> Option<Ident>;
}
impl DataExt for Data {
fn fields(&self) -> Vec<(&Visibility, TokenStream, &Type)> {
match self {
Data::Struct(strc) => strc.fields(),
Data::Enum(enm) => enm.fields(),
Data::Union(un) => un.fields(),
}
}
fn variants(&self) -> Vec<Vec<(&Visibility, TokenStream, &Type)>> {
match self {
Data::Struct(strc) => strc.variants(),
Data::Enum(enm) => enm.variants(),
Data::Union(un) => un.variants(),
}
}
fn tag(&self) -> Option<Ident> {
match self {
Data::Struct(strc) => strc.tag(),
Data::Enum(enm) => enm.tag(),
Data::Union(un) => un.tag(),
}
}
}
impl DataExt for DataStruct {
fn fields(&self) -> Vec<(&Visibility, TokenStream, &Type)> {
map_fields(&self.fields)
}
fn variants(&self) -> Vec<Vec<(&Visibility, TokenStream, &Type)>> {
vec![self.fields()]
}
fn tag(&self) -> Option<Ident> {
None
}
}
impl DataExt for DataEnum {
fn fields(&self) -> Vec<(&Visibility, TokenStream, &Type)> {
map_fields(self.variants.iter().flat_map(|var| &var.fields))
}
fn variants(&self) -> Vec<Vec<(&Visibility, TokenStream, &Type)>> {
self.variants.iter().map(|var| map_fields(&var.fields)).collect()
}
fn tag(&self) -> Option<Ident> {
Some(Ident::new("___ZerocopyTag", Span::call_site()))
}
}
impl DataExt for DataUnion {
fn fields(&self) -> Vec<(&Visibility, TokenStream, &Type)> {
map_fields(&self.fields.named)
}
fn variants(&self) -> Vec<Vec<(&Visibility, TokenStream, &Type)>> {
vec![self.fields()]
}
fn tag(&self) -> Option<Ident> {
None
}
}
fn map_fields<'a>(
fields: impl 'a + IntoIterator<Item = &'a Field>,
) -> Vec<(&'a Visibility, TokenStream, &'a Type)> {
fields
.into_iter()
.enumerate()
.map(|(idx, f)| {
(
&f.vis,
f.ident
.as_ref()
.map(ToTokens::to_token_stream)
.unwrap_or_else(|| Index::from(idx).to_token_stream()),
&f.ty,
)
})
.collect()
}

1883
vendor/zerocopy-derive/src/lib.rs vendored Normal file

File diff suppressed because it is too large Load Diff

2362
vendor/zerocopy-derive/src/output_tests.rs vendored Normal file

File diff suppressed because it is too large Load Diff

849
vendor/zerocopy-derive/src/repr.rs vendored Normal file
View File

@@ -0,0 +1,849 @@
// Copyright 2019 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.
use core::{
convert::{Infallible, TryFrom},
num::NonZeroU32,
};
use proc_macro2::{Span, TokenStream};
use quote::{quote_spanned, ToTokens, TokenStreamExt as _};
use syn::{
punctuated::Punctuated, spanned::Spanned as _, token::Comma, Attribute, Error, LitInt, Meta,
MetaList,
};
/// The computed representation of a type.
///
/// This is the result of processing all `#[repr(...)]` attributes on a type, if
/// any. A `Repr` is only capable of representing legal combinations of
/// `#[repr(...)]` attributes.
#[cfg_attr(test, derive(Copy, Clone, Debug))]
pub(crate) enum Repr<Prim, Packed> {
/// `#[repr(transparent)]`
Transparent(Span),
/// A compound representation: `repr(C)`, `repr(Rust)`, or `repr(Int)`
/// optionally combined with `repr(packed(...))` or `repr(align(...))`
Compound(Spanned<CompoundRepr<Prim>>, Option<Spanned<AlignRepr<Packed>>>),
}
/// A compound representation: `repr(C)`, `repr(Rust)`, or `repr(Int)`.
#[cfg_attr(test, derive(Copy, Clone, Debug, Eq, PartialEq))]
pub(crate) enum CompoundRepr<Prim> {
C,
Rust,
Primitive(Prim),
}
/// `repr(Int)`
#[derive(Copy, Clone)]
#[cfg_attr(test, derive(Debug, Eq, PartialEq))]
pub(crate) enum PrimitiveRepr {
U8,
U16,
U32,
U64,
U128,
Usize,
I8,
I16,
I32,
I64,
I128,
Isize,
}
/// `repr(packed(...))` or `repr(align(...))`
#[cfg_attr(test, derive(Copy, Clone, Debug, Eq, PartialEq))]
pub(crate) enum AlignRepr<Packed> {
Packed(Packed),
Align(NonZeroU32),
}
/// The representations which can legally appear on a struct or union type.
pub(crate) type StructUnionRepr = Repr<Infallible, NonZeroU32>;
/// The representations which can legally appear on an enum type.
pub(crate) type EnumRepr = Repr<PrimitiveRepr, Infallible>;
impl<Prim, Packed> Repr<Prim, Packed> {
/// Gets the name of this "repr type" - the non-align `repr(X)` that is used
/// in prose to refer to this type.
///
/// For example, we would refer to `#[repr(C, align(4))] struct Foo { ... }`
/// as a "`repr(C)` struct".
pub(crate) fn repr_type_name(&self) -> &str
where
Prim: Copy + With<PrimitiveRepr>,
{
use CompoundRepr::*;
use PrimitiveRepr::*;
use Repr::*;
match self {
Transparent(_span) => "repr(transparent)",
Compound(Spanned { t: repr, span: _ }, _align) => match repr {
C => "repr(C)",
Rust => "repr(Rust)",
Primitive(prim) => prim.with(|prim| match prim {
U8 => "repr(u8)",
U16 => "repr(u16)",
U32 => "repr(u32)",
U64 => "repr(u64)",
U128 => "repr(u128)",
Usize => "repr(usize)",
I8 => "repr(i8)",
I16 => "repr(i16)",
I32 => "repr(i32)",
I64 => "repr(i64)",
I128 => "repr(i128)",
Isize => "repr(isize)",
}),
},
}
}
pub(crate) fn is_transparent(&self) -> bool {
matches!(self, Repr::Transparent(_))
}
pub(crate) fn is_c(&self) -> bool {
use CompoundRepr::*;
matches!(self, Repr::Compound(Spanned { t: C, span: _ }, _align))
}
pub(crate) fn is_primitive(&self) -> bool {
use CompoundRepr::*;
matches!(self, Repr::Compound(Spanned { t: Primitive(_), span: _ }, _align))
}
pub(crate) fn get_packed(&self) -> Option<&Packed> {
use AlignRepr::*;
use Repr::*;
if let Compound(_, Some(Spanned { t: Packed(p), span: _ })) = self {
Some(p)
} else {
None
}
}
pub(crate) fn get_align(&self) -> Option<Spanned<NonZeroU32>> {
use AlignRepr::*;
use Repr::*;
if let Compound(_, Some(Spanned { t: Align(n), span })) = self {
Some(Spanned::new(*n, *span))
} else {
None
}
}
pub(crate) fn is_align_gt_1(&self) -> bool {
self.get_align().map(|n| n.t.get() > 1).unwrap_or(false)
}
/// When deriving `Unaligned`, validate that the decorated type has no
/// `#[repr(align(N))]` attribute where `N > 1`. If no such attribute exists
/// (including if `N == 1`), this returns `Ok(())`, and otherwise it returns
/// a descriptive error.
pub(crate) fn unaligned_validate_no_align_gt_1(&self) -> Result<(), Error> {
if let Some(n) = self.get_align().filter(|n| n.t.get() > 1) {
Err(Error::new(
n.span,
"cannot derive `Unaligned` on type with alignment greater than 1",
))
} else {
Ok(())
}
}
}
impl<Prim> Repr<Prim, NonZeroU32> {
/// Does `self` describe a `#[repr(packed)]` or `#[repr(packed(1))]` type?
pub(crate) fn is_packed_1(&self) -> bool {
self.get_packed().map(|n| n.get() == 1).unwrap_or(false)
}
}
impl<Packed> Repr<PrimitiveRepr, Packed> {
fn get_primitive(&self) -> Option<&PrimitiveRepr> {
use CompoundRepr::*;
use Repr::*;
if let Compound(Spanned { t: Primitive(p), span: _ }, _align) = self {
Some(p)
} else {
None
}
}
/// Does `self` describe a `#[repr(u8)]` type?
pub(crate) fn is_u8(&self) -> bool {
matches!(self.get_primitive(), Some(PrimitiveRepr::U8))
}
/// Does `self` describe a `#[repr(i8)]` type?
pub(crate) fn is_i8(&self) -> bool {
matches!(self.get_primitive(), Some(PrimitiveRepr::I8))
}
}
impl<Prim, Packed> ToTokens for Repr<Prim, Packed>
where
Prim: With<PrimitiveRepr> + Copy,
Packed: With<NonZeroU32> + Copy,
{
fn to_tokens(&self, ts: &mut TokenStream) {
use Repr::*;
match self {
Transparent(span) => ts.append_all(quote_spanned! { *span=> #[repr(transparent)] }),
Compound(repr, align) => {
repr.to_tokens(ts);
if let Some(align) = align {
align.to_tokens(ts);
}
}
}
}
}
impl<Prim: With<PrimitiveRepr> + Copy> ToTokens for Spanned<CompoundRepr<Prim>> {
fn to_tokens(&self, ts: &mut TokenStream) {
use CompoundRepr::*;
match &self.t {
C => ts.append_all(quote_spanned! { self.span=> #[repr(C)] }),
Rust => ts.append_all(quote_spanned! { self.span=> #[repr(Rust)] }),
Primitive(prim) => prim.with(|prim| Spanned::new(prim, self.span).to_tokens(ts)),
}
}
}
impl ToTokens for Spanned<PrimitiveRepr> {
fn to_tokens(&self, ts: &mut TokenStream) {
use PrimitiveRepr::*;
match self.t {
U8 => ts.append_all(quote_spanned! { self.span => #[repr(u8)] }),
U16 => ts.append_all(quote_spanned! { self.span => #[repr(u16)] }),
U32 => ts.append_all(quote_spanned! { self.span => #[repr(u32)] }),
U64 => ts.append_all(quote_spanned! { self.span => #[repr(u64)] }),
U128 => ts.append_all(quote_spanned! { self.span => #[repr(u128)] }),
Usize => ts.append_all(quote_spanned! { self.span => #[repr(usize)] }),
I8 => ts.append_all(quote_spanned! { self.span => #[repr(i8)] }),
I16 => ts.append_all(quote_spanned! { self.span => #[repr(i16)] }),
I32 => ts.append_all(quote_spanned! { self.span => #[repr(i32)] }),
I64 => ts.append_all(quote_spanned! { self.span => #[repr(i64)] }),
I128 => ts.append_all(quote_spanned! { self.span => #[repr(i128)] }),
Isize => ts.append_all(quote_spanned! { self.span => #[repr(isize)] }),
}
}
}
impl<Packed: With<NonZeroU32> + Copy> ToTokens for Spanned<AlignRepr<Packed>> {
fn to_tokens(&self, ts: &mut TokenStream) {
use AlignRepr::*;
// We use `syn::Index` instead of `u32` because `quote_spanned!`
// serializes `u32` literals as `123u32`, not just `123`. Rust doesn't
// recognize that as a valid argument to `#[repr(align(...))]` or
// `#[repr(packed(...))]`.
let to_index = |n: NonZeroU32| syn::Index { index: n.get(), span: self.span };
match self.t {
Packed(n) => n.with(|n| {
let n = to_index(n);
ts.append_all(quote_spanned! { self.span => #[repr(packed(#n))] })
}),
Align(n) => {
let n = to_index(n);
ts.append_all(quote_spanned! { self.span => #[repr(align(#n))] })
}
}
}
}
/// The result of parsing a single `#[repr(...)]` attribute or a single
/// directive inside a compound `#[repr(..., ...)]` attribute.
#[derive(Copy, Clone, PartialEq, Eq)]
#[cfg_attr(test, derive(Debug))]
pub(crate) enum RawRepr {
Transparent,
C,
Rust,
U8,
U16,
U32,
U64,
U128,
Usize,
I8,
I16,
I32,
I64,
I128,
Isize,
Align(NonZeroU32),
PackedN(NonZeroU32),
Packed,
}
/// The error from converting from a `RawRepr`.
#[cfg_attr(test, derive(Debug, Eq, PartialEq))]
pub(crate) enum FromRawReprError<E> {
/// The `RawRepr` doesn't affect the high-level repr we're parsing (e.g.
/// it's `align(...)` and we're parsing a `CompoundRepr`).
None,
/// The `RawRepr` is invalid for the high-level repr we're parsing (e.g.
/// it's `packed` repr and we're parsing an `AlignRepr` for an enum type).
Err(E),
}
/// The representation hint is not supported for the decorated type.
#[cfg_attr(test, derive(Copy, Clone, Debug, Eq, PartialEq))]
pub(crate) struct UnsupportedReprError;
impl<Prim: With<PrimitiveRepr>> TryFrom<RawRepr> for CompoundRepr<Prim> {
type Error = FromRawReprError<UnsupportedReprError>;
fn try_from(
raw: RawRepr,
) -> Result<CompoundRepr<Prim>, FromRawReprError<UnsupportedReprError>> {
use RawRepr::*;
match raw {
C => Ok(CompoundRepr::C),
Rust => Ok(CompoundRepr::Rust),
raw @ (U8 | U16 | U32 | U64 | U128 | Usize | I8 | I16 | I32 | I64 | I128 | Isize) => {
Prim::try_with_or(
|| match raw {
U8 => Ok(PrimitiveRepr::U8),
U16 => Ok(PrimitiveRepr::U16),
U32 => Ok(PrimitiveRepr::U32),
U64 => Ok(PrimitiveRepr::U64),
U128 => Ok(PrimitiveRepr::U128),
Usize => Ok(PrimitiveRepr::Usize),
I8 => Ok(PrimitiveRepr::I8),
I16 => Ok(PrimitiveRepr::I16),
I32 => Ok(PrimitiveRepr::I32),
I64 => Ok(PrimitiveRepr::I64),
I128 => Ok(PrimitiveRepr::I128),
Isize => Ok(PrimitiveRepr::Isize),
Transparent | C | Rust | Align(_) | PackedN(_) | Packed => {
Err(UnsupportedReprError)
}
},
UnsupportedReprError,
)
.map(CompoundRepr::Primitive)
.map_err(FromRawReprError::Err)
}
Transparent | Align(_) | PackedN(_) | Packed => Err(FromRawReprError::None),
}
}
}
impl<Pcked: With<NonZeroU32>> TryFrom<RawRepr> for AlignRepr<Pcked> {
type Error = FromRawReprError<UnsupportedReprError>;
fn try_from(raw: RawRepr) -> Result<AlignRepr<Pcked>, FromRawReprError<UnsupportedReprError>> {
use RawRepr::*;
match raw {
Packed | PackedN(_) => Pcked::try_with_or(
|| match raw {
Packed => Ok(NonZeroU32::new(1).unwrap()),
PackedN(n) => Ok(n),
U8 | U16 | U32 | U64 | U128 | Usize | I8 | I16 | I32 | I64 | I128 | Isize
| Transparent | C | Rust | Align(_) => Err(UnsupportedReprError),
},
UnsupportedReprError,
)
.map(AlignRepr::Packed)
.map_err(FromRawReprError::Err),
Align(n) => Ok(AlignRepr::Align(n)),
U8 | U16 | U32 | U64 | U128 | Usize | I8 | I16 | I32 | I64 | I128 | Isize
| Transparent | C | Rust => Err(FromRawReprError::None),
}
}
}
/// The error from extracting a high-level repr type from a list of `RawRepr`s.
#[cfg_attr(test, derive(Copy, Clone, Debug, Eq, PartialEq))]
enum FromRawReprsError<E> {
/// One of the `RawRepr`s is invalid for the high-level repr we're parsing
/// (e.g. there's a `packed` repr and we're parsing an `AlignRepr` for an
/// enum type).
Single(E),
/// Two `RawRepr`s appear which both affect the high-level repr we're
/// parsing (e.g., the list is `#[repr(align(2), packed)]`). Note that we
/// conservatively treat redundant reprs as conflicting (e.g.
/// `#[repr(packed, packed)]`).
Conflict,
}
/// Tries to extract a high-level repr from a list of `RawRepr`s.
fn try_from_raw_reprs<'a, E, R: TryFrom<RawRepr, Error = FromRawReprError<E>>>(
r: impl IntoIterator<Item = &'a Spanned<RawRepr>>,
) -> Result<Option<Spanned<R>>, Spanned<FromRawReprsError<E>>> {
// Walk the list of `RawRepr`s and attempt to convert each to an `R`. Bail
// if we find any errors. If we find more than one which converts to an `R`,
// bail with a `Conflict` error.
r.into_iter().try_fold(None, |found: Option<Spanned<R>>, raw| {
let new = match Spanned::<R>::try_from(*raw) {
Ok(r) => r,
// This `RawRepr` doesn't convert to an `R`, so keep the current
// found `R`, if any.
Err(FromRawReprError::None) => return Ok(found),
// This repr is unsupported for the decorated type (e.g.
// `repr(packed)` on an enum).
Err(FromRawReprError::Err(Spanned { t: err, span })) => {
return Err(Spanned::new(FromRawReprsError::Single(err), span))
}
};
if let Some(found) = found {
// We already found an `R`, but this `RawRepr` also converts to an
// `R`, so that's a conflict.
//
// `Span::join` returns `None` if the two spans are from different
// files or if we're not on the nightly compiler. In that case, just
// use `new`'s span.
let span = found.span.join(new.span).unwrap_or(new.span);
Err(Spanned::new(FromRawReprsError::Conflict, span))
} else {
Ok(Some(new))
}
})
}
/// The error returned from [`Repr::from_attrs`].
#[cfg_attr(test, derive(Copy, Clone, Debug, Eq, PartialEq))]
enum FromAttrsError {
FromRawReprs(FromRawReprsError<UnsupportedReprError>),
Unrecognized,
}
impl From<FromRawReprsError<UnsupportedReprError>> for FromAttrsError {
fn from(err: FromRawReprsError<UnsupportedReprError>) -> FromAttrsError {
FromAttrsError::FromRawReprs(err)
}
}
impl From<UnrecognizedReprError> for FromAttrsError {
fn from(_err: UnrecognizedReprError) -> FromAttrsError {
FromAttrsError::Unrecognized
}
}
impl From<Spanned<FromAttrsError>> for Error {
fn from(err: Spanned<FromAttrsError>) -> Error {
let Spanned { t: err, span } = err;
match err {
FromAttrsError::FromRawReprs(FromRawReprsError::Single(
_err @ UnsupportedReprError,
)) => Error::new(span, "unsupported representation hint for the decorated type"),
FromAttrsError::FromRawReprs(FromRawReprsError::Conflict) => {
// NOTE: This says "another" rather than "a preceding" because
// when one of the reprs involved is `transparent`, we detect
// that condition in `Repr::from_attrs`, and at that point we
// can't tell which repr came first, so we might report this on
// the first involved repr rather than the second, third, etc.
Error::new(span, "this conflicts with another representation hint")
}
FromAttrsError::Unrecognized => Error::new(span, "unrecognized representation hint"),
}
}
}
impl<Prim, Packed> Repr<Prim, Packed> {
fn from_attrs_inner(attrs: &[Attribute]) -> Result<Repr<Prim, Packed>, Spanned<FromAttrsError>>
where
Prim: With<PrimitiveRepr>,
Packed: With<NonZeroU32>,
{
let raw_reprs = RawRepr::from_attrs(attrs).map_err(Spanned::from)?;
let transparent = {
let mut transparents = raw_reprs.iter().filter_map(|Spanned { t, span }| match t {
RawRepr::Transparent => Some(span),
_ => None,
});
let first = transparents.next();
let second = transparents.next();
match (first, second) {
(None, None) => None,
(Some(span), None) => Some(*span),
(Some(_), Some(second)) => {
return Err(Spanned::new(
FromAttrsError::FromRawReprs(FromRawReprsError::Conflict),
*second,
))
}
// An iterator can't produce a value only on the second call to
// `.next()`.
(None, Some(_)) => unreachable!(),
}
};
let compound: Option<Spanned<CompoundRepr<Prim>>> =
try_from_raw_reprs(raw_reprs.iter()).map_err(Spanned::from)?;
let align: Option<Spanned<AlignRepr<Packed>>> =
try_from_raw_reprs(raw_reprs.iter()).map_err(Spanned::from)?;
if let Some(span) = transparent {
if compound.is_some() || align.is_some() {
// Arbitrarily report the problem on the `transparent` span. Any
// span will do.
return Err(Spanned::new(FromRawReprsError::Conflict.into(), span));
}
Ok(Repr::Transparent(span))
} else {
Ok(Repr::Compound(
compound.unwrap_or(Spanned::new(CompoundRepr::Rust, Span::call_site())),
align,
))
}
}
}
impl<Prim, Packed> Repr<Prim, Packed> {
pub(crate) fn from_attrs(attrs: &[Attribute]) -> Result<Repr<Prim, Packed>, Error>
where
Prim: With<PrimitiveRepr>,
Packed: With<NonZeroU32>,
{
Repr::from_attrs_inner(attrs).map_err(Into::into)
}
}
/// The representation hint could not be parsed or was unrecognized.
struct UnrecognizedReprError;
impl RawRepr {
fn from_attrs(
attrs: &[Attribute],
) -> Result<Vec<Spanned<RawRepr>>, Spanned<UnrecognizedReprError>> {
let mut reprs = Vec::new();
for attr in attrs {
// Ignore documentation attributes.
if attr.path().is_ident("doc") {
continue;
}
if let Meta::List(ref meta_list) = attr.meta {
if meta_list.path.is_ident("repr") {
let parsed: Punctuated<Meta, Comma> =
match meta_list.parse_args_with(Punctuated::parse_terminated) {
Ok(parsed) => parsed,
Err(_) => {
return Err(Spanned::new(
UnrecognizedReprError,
meta_list.tokens.span(),
))
}
};
for meta in parsed {
let s = meta.span();
reprs.push(
RawRepr::from_meta(&meta)
.map(|r| Spanned::new(r, s))
.map_err(|e| Spanned::new(e, s))?,
);
}
}
}
}
Ok(reprs)
}
fn from_meta(meta: &Meta) -> Result<RawRepr, UnrecognizedReprError> {
let (path, list) = match meta {
Meta::Path(path) => (path, None),
Meta::List(list) => (&list.path, Some(list)),
_ => return Err(UnrecognizedReprError),
};
let ident = path.get_ident().ok_or(UnrecognizedReprError)?;
// Only returns `Ok` for non-zero power-of-two values.
let parse_nzu64 = |list: &MetaList| {
list.parse_args::<LitInt>()
.and_then(|int| int.base10_parse::<NonZeroU32>())
.map_err(|_| UnrecognizedReprError)
.and_then(|nz| {
if nz.get().is_power_of_two() {
Ok(nz)
} else {
Err(UnrecognizedReprError)
}
})
};
use RawRepr::*;
Ok(match (ident.to_string().as_str(), list) {
("u8", None) => U8,
("u16", None) => U16,
("u32", None) => U32,
("u64", None) => U64,
("u128", None) => U128,
("usize", None) => Usize,
("i8", None) => I8,
("i16", None) => I16,
("i32", None) => I32,
("i64", None) => I64,
("i128", None) => I128,
("isize", None) => Isize,
("C", None) => C,
("transparent", None) => Transparent,
("Rust", None) => Rust,
("packed", None) => Packed,
("packed", Some(list)) => PackedN(parse_nzu64(list)?),
("align", Some(list)) => Align(parse_nzu64(list)?),
_ => return Err(UnrecognizedReprError),
})
}
}
pub(crate) use util::*;
mod util {
use super::*;
/// A value with an associated span.
#[derive(Copy, Clone)]
#[cfg_attr(test, derive(Debug))]
pub(crate) struct Spanned<T> {
pub(crate) t: T,
pub(crate) span: Span,
}
impl<T> Spanned<T> {
pub(super) fn new(t: T, span: Span) -> Spanned<T> {
Spanned { t, span }
}
pub(super) fn from<U>(s: Spanned<U>) -> Spanned<T>
where
T: From<U>,
{
let Spanned { t: u, span } = s;
Spanned::new(u.into(), span)
}
/// Delegates to `T: TryFrom`, preserving span information in both the
/// success and error cases.
pub(super) fn try_from<E, U>(
u: Spanned<U>,
) -> Result<Spanned<T>, FromRawReprError<Spanned<E>>>
where
T: TryFrom<U, Error = FromRawReprError<E>>,
{
let Spanned { t: u, span } = u;
T::try_from(u).map(|t| Spanned { t, span }).map_err(|err| match err {
FromRawReprError::None => FromRawReprError::None,
FromRawReprError::Err(e) => FromRawReprError::Err(Spanned::new(e, span)),
})
}
}
// Used to permit implementing `With<T> for T: Inhabited` and for
// `Infallible` without a blanket impl conflict.
pub(crate) trait Inhabited {}
impl Inhabited for PrimitiveRepr {}
impl Inhabited for NonZeroU32 {}
pub(crate) trait With<T> {
fn with<O, F: FnOnce(T) -> O>(self, f: F) -> O;
fn try_with_or<E, F: FnOnce() -> Result<T, E>>(f: F, err: E) -> Result<Self, E>
where
Self: Sized;
}
impl<T: Inhabited> With<T> for T {
fn with<O, F: FnOnce(T) -> O>(self, f: F) -> O {
f(self)
}
fn try_with_or<E, F: FnOnce() -> Result<T, E>>(f: F, _err: E) -> Result<Self, E> {
f()
}
}
impl<T> With<T> for Infallible {
fn with<O, F: FnOnce(T) -> O>(self, _f: F) -> O {
match self {}
}
fn try_with_or<E, F: FnOnce() -> Result<T, E>>(_f: F, err: E) -> Result<Self, E> {
Err(err)
}
}
}
#[cfg(test)]
mod tests {
use syn::parse_quote;
use super::*;
impl<T> From<T> for Spanned<T> {
fn from(t: T) -> Spanned<T> {
Spanned::new(t, Span::call_site())
}
}
// We ignore spans for equality in testing since real spans are hard to
// synthesize and don't implement `PartialEq`.
impl<T: PartialEq> PartialEq for Spanned<T> {
fn eq(&self, other: &Spanned<T>) -> bool {
self.t.eq(&other.t)
}
}
impl<T: Eq> Eq for Spanned<T> {}
impl<Prim: PartialEq, Packed: PartialEq> PartialEq for Repr<Prim, Packed> {
fn eq(&self, other: &Repr<Prim, Packed>) -> bool {
match (self, other) {
(Repr::Transparent(_), Repr::Transparent(_)) => true,
(Repr::Compound(sc, sa), Repr::Compound(oc, oa)) => (sc, sa) == (oc, oa),
_ => false,
}
}
}
fn s() -> Span {
Span::call_site()
}
#[test]
fn test() {
// Test that a given `#[repr(...)]` attribute parses and returns the
// given `Repr` or error.
macro_rules! test {
($(#[$attr:meta])* => $repr:expr) => {
test!(@inner $(#[$attr])* => Repr => Ok($repr));
};
// In the error case, the caller must explicitly provide the name of
// the `Repr` type to assist in type inference.
(@error $(#[$attr:meta])* => $typ:ident => $repr:expr) => {
test!(@inner $(#[$attr])* => $typ => Err($repr));
};
(@inner $(#[$attr:meta])* => $typ:ident => $repr:expr) => {
let attr: Attribute = parse_quote!($(#[$attr])*);
let mut got = $typ::from_attrs_inner(&[attr]);
let expect: Result<Repr<_, _>, _> = $repr;
if false {
// Force Rust to infer `got` as having the same type as
// `expect`.
got = expect;
}
assert_eq!(got, expect, stringify!($(#[$attr])*));
};
}
use AlignRepr::*;
use CompoundRepr::*;
use PrimitiveRepr::*;
let nz = |n: u32| NonZeroU32::new(n).unwrap();
test!(#[repr(transparent)] => StructUnionRepr::Transparent(s()));
test!(#[repr()] => StructUnionRepr::Compound(Rust.into(), None));
test!(#[repr(packed)] => StructUnionRepr::Compound(Rust.into(), Some(Packed(nz(1)).into())));
test!(#[repr(packed(2))] => StructUnionRepr::Compound(Rust.into(), Some(Packed(nz(2)).into())));
test!(#[repr(align(1))] => StructUnionRepr::Compound(Rust.into(), Some(Align(nz(1)).into())));
test!(#[repr(align(2))] => StructUnionRepr::Compound(Rust.into(), Some(Align(nz(2)).into())));
test!(#[repr(C)] => StructUnionRepr::Compound(C.into(), None));
test!(#[repr(C, packed)] => StructUnionRepr::Compound(C.into(), Some(Packed(nz(1)).into())));
test!(#[repr(C, packed(2))] => StructUnionRepr::Compound(C.into(), Some(Packed(nz(2)).into())));
test!(#[repr(C, align(1))] => StructUnionRepr::Compound(C.into(), Some(Align(nz(1)).into())));
test!(#[repr(C, align(2))] => StructUnionRepr::Compound(C.into(), Some(Align(nz(2)).into())));
test!(#[repr(transparent)] => EnumRepr::Transparent(s()));
test!(#[repr()] => EnumRepr::Compound(Rust.into(), None));
test!(#[repr(align(1))] => EnumRepr::Compound(Rust.into(), Some(Align(nz(1)).into())));
test!(#[repr(align(2))] => EnumRepr::Compound(Rust.into(), Some(Align(nz(2)).into())));
macro_rules! for_each_compound_repr {
($($r:tt => $var:expr),*) => {
$(
test!(#[repr($r)] => EnumRepr::Compound($var.into(), None));
test!(#[repr($r, align(1))] => EnumRepr::Compound($var.into(), Some(Align(nz(1)).into())));
test!(#[repr($r, align(2))] => EnumRepr::Compound($var.into(), Some(Align(nz(2)).into())));
)*
}
}
for_each_compound_repr!(
C => C,
u8 => Primitive(U8),
u16 => Primitive(U16),
u32 => Primitive(U32),
u64 => Primitive(U64),
usize => Primitive(Usize),
i8 => Primitive(I8),
i16 => Primitive(I16),
i32 => Primitive(I32),
i64 => Primitive(I64),
isize => Primitive(Isize)
);
use FromAttrsError::*;
use FromRawReprsError::*;
// Run failure tests which are valid for both `StructUnionRepr` and
// `EnumRepr`.
macro_rules! for_each_repr_type {
($($repr:ident),*) => {
$(
// Invalid packed or align attributes
test!(@error #[repr(packed(0))] => $repr => Unrecognized.into());
test!(@error #[repr(packed(3))] => $repr => Unrecognized.into());
test!(@error #[repr(align(0))] => $repr => Unrecognized.into());
test!(@error #[repr(align(3))] => $repr => Unrecognized.into());
// Conflicts
test!(@error #[repr(transparent, transparent)] => $repr => FromRawReprs(Conflict).into());
test!(@error #[repr(transparent, C)] => $repr => FromRawReprs(Conflict).into());
test!(@error #[repr(transparent, Rust)] => $repr => FromRawReprs(Conflict).into());
test!(@error #[repr(C, transparent)] => $repr => FromRawReprs(Conflict).into());
test!(@error #[repr(C, C)] => $repr => FromRawReprs(Conflict).into());
test!(@error #[repr(C, Rust)] => $repr => FromRawReprs(Conflict).into());
test!(@error #[repr(Rust, transparent)] => $repr => FromRawReprs(Conflict).into());
test!(@error #[repr(Rust, C)] => $repr => FromRawReprs(Conflict).into());
test!(@error #[repr(Rust, Rust)] => $repr => FromRawReprs(Conflict).into());
)*
}
}
for_each_repr_type!(StructUnionRepr, EnumRepr);
// Enum-specific conflicts.
//
// We don't bother to test every combination since that would be a huge
// number (enums can have primitive reprs u8, u16, u32, u64, usize, i8,
// i16, i32, i64, and isize). Instead, since the conflict logic doesn't
// care what specific value of `PrimitiveRepr` is present, we assume
// that testing against u8 alone is fine.
test!(@error #[repr(transparent, u8)] => EnumRepr => FromRawReprs(Conflict).into());
test!(@error #[repr(u8, transparent)] => EnumRepr => FromRawReprs(Conflict).into());
test!(@error #[repr(C, u8)] => EnumRepr => FromRawReprs(Conflict).into());
test!(@error #[repr(u8, C)] => EnumRepr => FromRawReprs(Conflict).into());
test!(@error #[repr(Rust, u8)] => EnumRepr => FromRawReprs(Conflict).into());
test!(@error #[repr(u8, Rust)] => EnumRepr => FromRawReprs(Conflict).into());
test!(@error #[repr(u8, u8)] => EnumRepr => FromRawReprs(Conflict).into());
// Illegal struct/union reprs
test!(@error #[repr(u8)] => StructUnionRepr => FromRawReprs(Single(UnsupportedReprError)).into());
test!(@error #[repr(u16)] => StructUnionRepr => FromRawReprs(Single(UnsupportedReprError)).into());
test!(@error #[repr(u32)] => StructUnionRepr => FromRawReprs(Single(UnsupportedReprError)).into());
test!(@error #[repr(u64)] => StructUnionRepr => FromRawReprs(Single(UnsupportedReprError)).into());
test!(@error #[repr(usize)] => StructUnionRepr => FromRawReprs(Single(UnsupportedReprError)).into());
test!(@error #[repr(i8)] => StructUnionRepr => FromRawReprs(Single(UnsupportedReprError)).into());
test!(@error #[repr(i16)] => StructUnionRepr => FromRawReprs(Single(UnsupportedReprError)).into());
test!(@error #[repr(i32)] => StructUnionRepr => FromRawReprs(Single(UnsupportedReprError)).into());
test!(@error #[repr(i64)] => StructUnionRepr => FromRawReprs(Single(UnsupportedReprError)).into());
test!(@error #[repr(isize)] => StructUnionRepr => FromRawReprs(Single(UnsupportedReprError)).into());
// Illegal enum reprs
test!(@error #[repr(packed)] => EnumRepr => FromRawReprs(Single(UnsupportedReprError)).into());
test!(@error #[repr(packed(1))] => EnumRepr => FromRawReprs(Single(UnsupportedReprError)).into());
test!(@error #[repr(packed(2))] => EnumRepr => FromRawReprs(Single(UnsupportedReprError)).into());
}
}

View File

@@ -0,0 +1,189 @@
// Copyright 2024 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.
// Make sure that the derive macros will respect the
// `#[zerocopy(crate = "...")]` attribute when renaming the crate.
// See comment in `include.rs` for why we disable the prelude.
#![no_implicit_prelude]
#![allow(warnings)]
include!("include.rs");
#[test]
fn test_gen_custom_zerocopy() {
#[derive(
imp::ByteEq,
imp::ByteHash,
imp::IntoBytes,
imp::FromBytes,
imp::Unaligned,
imp::Immutable,
imp::KnownLayout,
)]
#[zerocopy(crate = "fake_zerocopy")]
#[repr(packed)]
struct SomeStruct {
a: u16,
b: u32,
}
impl AssertNotZerocopyIntoBytes for SomeStruct {}
impl AssertNotZerocopyFromBytes for SomeStruct {}
impl AssertNotZerocopyUnaligned for SomeStruct {}
impl AssertNotZerocopyImmutable for SomeStruct {}
impl AssertNotZerocopyKnownLayout for SomeStruct {}
fake_zerocopy::assert::<SomeStruct>();
}
mod fake_zerocopy {
use ::std::{io, ptr::NonNull, unimplemented};
pub use super::imp::*;
pub fn assert<T>()
where
T: IntoBytes + FromBytes + Unaligned + Immutable,
{
}
pub unsafe trait IntoBytes {
fn only_derive_is_allowed_to_implement_this_trait()
where
Self: Sized;
fn as_bytes(&self) -> &[u8]
where
Self: Immutable,
{
unimplemented!()
}
}
pub unsafe trait FromBytes: FromZeros {
fn only_derive_is_allowed_to_implement_this_trait()
where
Self: Sized;
}
pub unsafe trait Unaligned {
fn only_derive_is_allowed_to_implement_this_trait()
where
Self: Sized;
}
pub unsafe trait Immutable {
fn only_derive_is_allowed_to_implement_this_trait()
where
Self: Sized;
}
pub unsafe trait KnownLayout {
fn only_derive_is_allowed_to_implement_this_trait()
where
Self: Sized;
type PointerMetadata: PointerMetadata;
type MaybeUninit: ?Sized + KnownLayout<PointerMetadata = Self::PointerMetadata>;
const LAYOUT: DstLayout;
fn raw_from_ptr_len(bytes: NonNull<u8>, meta: Self::PointerMetadata) -> NonNull<Self>;
fn pointer_to_metadata(ptr: *mut Self) -> Self::PointerMetadata;
}
macro_rules! impl_ty {
($ty:ty $(as $generic:ident)?) => {
unsafe impl$(<$generic: IntoBytes>)? IntoBytes for $ty {
fn only_derive_is_allowed_to_implement_this_trait()
where
Self: Sized,
{
unimplemented!()
}
}
unsafe impl$(<$generic: FromBytes>)? FromBytes for $ty {
fn only_derive_is_allowed_to_implement_this_trait()
where
Self: Sized,
{
unimplemented!()
}
}
unsafe impl$(<$generic: Unaligned>)? Unaligned for $ty {
fn only_derive_is_allowed_to_implement_this_trait()
where
Self: Sized,
{
unimplemented!()
}
}
unsafe impl$(<$generic: Immutable>)? Immutable for $ty {
fn only_derive_is_allowed_to_implement_this_trait()
where
Self: Sized,
{
unimplemented!()
}
}
unsafe impl$(<$generic: KnownLayout>)? KnownLayout for $ty {
fn only_derive_is_allowed_to_implement_this_trait()
where
Self: Sized,
{
unimplemented!()
}
type PointerMetadata = ();
type MaybeUninit = ();
const LAYOUT: DstLayout = DstLayout::new_zst(None);
fn raw_from_ptr_len(
bytes: NonNull<u8>,
meta: Self::PointerMetadata,
) -> NonNull<Self> {
unimplemented!()
}
fn pointer_to_metadata(ptr: *mut Self) -> Self::PointerMetadata {
unimplemented!()
}
}
};
}
impl_ty!(());
impl_ty!(u16);
impl_ty!(u32);
impl_ty!([T] as T);
impl_ty!(::std::mem::MaybeUninit<T> as T);
}
pub trait AssertNotZerocopyIntoBytes {}
impl<T: imp::IntoBytes> AssertNotZerocopyIntoBytes for T {}
pub trait AssertNotZerocopyFromBytes {}
impl<T: imp::FromBytes> AssertNotZerocopyFromBytes for T {}
pub trait AssertNotZerocopyUnaligned {}
impl<T: imp::Unaligned> AssertNotZerocopyUnaligned for T {}
pub trait AssertNotZerocopyImmutable {}
impl<T: imp::Immutable> AssertNotZerocopyImmutable for T {}
pub trait AssertNotZerocopyKnownLayout {}
impl<T: imp::KnownLayout> AssertNotZerocopyKnownLayout for T {}

View File

@@ -0,0 +1,48 @@
// Copyright 2024 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.
// See comment in `include.rs` for why we disable the prelude.
#![no_implicit_prelude]
#![allow(warnings)]
#![deny(deprecated)]
include!("include.rs");
// Make sure no deprecation warnings are generated from our derives (see #553).
#[macro_export]
macro_rules! test {
($name:ident => $ty:item => $($trait:ident),*) => {
#[allow(non_snake_case)]
mod $name {
$(
mod $trait {
use super::super::*;
#[deprecated = "do not use"]
#[derive(imp::$trait)]
$ty
#[allow(deprecated)]
fn _allow_deprecated() {
util_assert_impl_all!($name: imp::$trait);
}
}
)*
}
};
}
// NOTE: `FromBytes` is tested separately in `enum_from_bytes.rs` since it
// requires 256-variant enums which are extremely verbose; such enums are
// already in that file.
test!(Enum => #[repr(u8)] enum Enum { A, } => TryFromBytes, FromZeros, KnownLayout, Immutable, IntoBytes, Unaligned);
test!(Struct => #[repr(C)] struct Struct; => TryFromBytes, FromZeros, FromBytes, KnownLayout, Immutable, IntoBytes, Unaligned);
test!(Union => #[repr(C)] union Union{ a: (), } => TryFromBytes, FromZeros, FromBytes, KnownLayout, Immutable, IntoBytes, Unaligned);

View File

@@ -0,0 +1,99 @@
// Copyright 2019 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.
// See comment in `include.rs` for why we disable the prelude.
#![no_implicit_prelude]
#![allow(warnings)]
include!("include.rs");
#[derive(imp::FromZeros)]
#[repr(C)]
enum Foo {
A,
}
util_assert_impl_all!(Foo: imp::FromZeros);
#[derive(imp::FromZeros)]
#[repr(C)]
enum Bar {
A = 0,
}
util_assert_impl_all!(Bar: imp::FromZeros);
#[derive(imp::FromZeros)]
#[repr(C)]
enum TwoVariantsHasExplicitZero {
A = 1,
B = 0,
}
util_assert_impl_all!(TwoVariantsHasExplicitZero: imp::FromZeros);
#[derive(imp::FromZeros)]
#[repr(i8)]
enum ImplicitNonFirstVariantIsZero {
A = -1,
B,
}
util_assert_impl_all!(ImplicitNonFirstVariantIsZero: imp::FromZeros);
#[derive(imp::FromZeros)]
#[repr(u64)]
enum LargeDiscriminant {
A = 0xFFFF_FFFF_FFFF_FFFF,
B = 0x0000_0000_0000_0000,
}
util_assert_impl_all!(LargeDiscriminant: imp::FromZeros);
#[derive(imp::FromZeros)]
#[repr(C)]
enum FirstVariantIsZeroable {
A(u32),
B { foo: u32 },
}
util_assert_impl_all!(FirstVariantIsZeroable: imp::FromZeros);
#[derive(imp::FromZeros)]
#[repr(u8)]
enum FirstVariantIsZeroableSecondIsNot {
A(bool),
B(::core::num::NonZeroU8),
}
util_assert_impl_all!(FirstVariantIsZeroableSecondIsNot: imp::FromZeros);
// MSRV does not support data-carrying enum variants with explicit discriminants
#[cfg(not(__ZEROCOPY_TOOLCHAIN = "msrv"))]
mod msrv_only {
use super::*;
#[derive(imp::FromZeros)]
#[repr(u8)]
enum ImplicitFirstVariantIsZeroable {
A(bool),
B(::core::num::NonZeroU8) = 1,
}
util_assert_impl_all!(ImplicitFirstVariantIsZeroable: imp::FromZeros);
#[derive(imp::FromZeros)]
#[repr(i8)]
enum ImplicitNonFirstVariantIsZeroable {
A(::core::num::NonZeroU8) = 1,
B = -1,
C(bool),
}
util_assert_impl_all!(ImplicitNonFirstVariantIsZeroable: imp::FromZeros);
}

View File

@@ -0,0 +1,50 @@
// Copyright 2023 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.
// See comment in `include.rs` for why we disable the prelude.
#![no_implicit_prelude]
#![allow(warnings)]
include!("include.rs");
#[derive(imp::KnownLayout)]
enum Foo {
A,
}
util_assert_impl_all!(Foo: imp::KnownLayout);
#[derive(imp::KnownLayout)]
enum Bar {
A = 0,
}
util_assert_impl_all!(Bar: imp::KnownLayout);
#[derive(imp::KnownLayout)]
enum Baz {
A = 1,
B = 0,
}
util_assert_impl_all!(Baz: imp::KnownLayout);
// Deriving `KnownLayout` should work if the enum has bounded parameters.
#[derive(imp::KnownLayout)]
#[repr(C)]
enum WithParams<'a: 'b, 'b: 'a, T: 'a + 'b + imp::KnownLayout, const N: usize>
where
'a: 'b,
'b: 'a,
T: 'a + 'b + imp::KnownLayout,
{
Variant([T; N], imp::PhantomData<&'a &'b ()>),
}
util_assert_impl_all!(WithParams<'static, 'static, u8, 42>: imp::KnownLayout);

View File

@@ -0,0 +1,51 @@
// Copyright 2023 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.
// See comment in `include.rs` for why we disable the prelude.
#![no_implicit_prelude]
#![allow(warnings)]
include!("include.rs");
#[derive(imp::Immutable)]
enum Foo {
A,
}
util_assert_impl_all!(Foo: imp::Immutable);
#[derive(imp::Immutable)]
enum Bar {
A = 0,
}
util_assert_impl_all!(Bar: imp::Immutable);
#[derive(imp::Immutable)]
enum Baz {
A = 1,
B = 0,
}
util_assert_impl_all!(Baz: imp::Immutable);
// Deriving `Immutable` should work if the enum has bounded parameters.
#[derive(imp::Immutable)]
#[repr(C)]
enum WithParams<'a: 'b, 'b: 'a, T: 'a + 'b + imp::Immutable, const N: ::core::primitive::usize>
where
'a: 'b,
'b: 'a,
T: 'a + 'b + imp::Immutable,
{
Variant([T; N], imp::PhantomData<&'a &'b ()>),
UnsafeCell(imp::PhantomData<imp::UnsafeCell<()>>, &'a imp::UnsafeCell<()>),
}
util_assert_impl_all!(WithParams<'static, 'static, u8, 42>: imp::Immutable);

View File

@@ -0,0 +1,133 @@
// Copyright 2019 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.
// See comment in `include.rs` for why we disable the prelude.
#![no_implicit_prelude]
#![allow(warnings)]
include!("include.rs");
// An enum is `IntoBytes` if if has a defined repr.
#[derive(imp::IntoBytes)]
#[repr(C)]
enum C {
A,
}
util_assert_impl_all!(C: imp::IntoBytes);
#[derive(imp::IntoBytes)]
#[repr(u8)]
enum U8 {
A,
}
util_assert_impl_all!(U8: imp::IntoBytes);
#[derive(imp::IntoBytes)]
#[repr(u16)]
enum U16 {
A,
}
util_assert_impl_all!(U16: imp::IntoBytes);
#[derive(imp::IntoBytes)]
#[repr(u32)]
enum U32 {
A,
}
util_assert_impl_all!(U32: imp::IntoBytes);
#[derive(imp::IntoBytes)]
#[repr(u64)]
enum U64 {
A,
}
util_assert_impl_all!(U64: imp::IntoBytes);
#[derive(imp::IntoBytes)]
#[repr(usize)]
enum Usize {
A,
}
util_assert_impl_all!(Usize: imp::IntoBytes);
#[derive(imp::IntoBytes)]
#[repr(i8)]
enum I8 {
A,
}
util_assert_impl_all!(I8: imp::IntoBytes);
#[derive(imp::IntoBytes)]
#[repr(i16)]
enum I16 {
A,
}
util_assert_impl_all!(I16: imp::IntoBytes);
#[derive(imp::IntoBytes)]
#[repr(i32)]
enum I32 {
A,
}
util_assert_impl_all!(I32: imp::IntoBytes);
#[derive(imp::IntoBytes)]
#[repr(i64)]
enum I64 {
A,
}
util_assert_impl_all!(I64: imp::IntoBytes);
#[derive(imp::IntoBytes)]
#[repr(isize)]
enum Isize {
A,
}
util_assert_impl_all!(Isize: imp::IntoBytes);
#[derive(imp::IntoBytes)]
#[repr(u8)]
enum HasData {
A(u8),
B(i8),
}
util_assert_impl_all!(HasData: imp::IntoBytes);
#[derive(imp::IntoBytes)]
#[repr(u32)]
enum HasData32 {
A(u32),
B(i32),
C([u8; 4]),
D([u16; 2]),
}
util_assert_impl_all!(HasData: imp::IntoBytes);
// After #1752 landed but before #1758 was fixed, this failed to compile because
// the padding check treated the tag type as being `#[repr(u8, align(2))] struct
// Tag { A }`, which is two bytes long, rather than the correct `#[repr(u8)]
// struct Tag { A }`, which is one byte long.
#[derive(imp::IntoBytes)]
#[repr(u8, align(2))]
enum BadTagWouldHavePadding {
A(u8, u16),
}

View File

@@ -0,0 +1,644 @@
// Copyright 2023 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.
// See comment in `include.rs` for why we disable the prelude.
#![no_implicit_prelude]
#![allow(warnings)]
include!("include.rs");
#[derive(Eq, PartialEq, Debug, imp::Immutable, imp::KnownLayout, imp::TryFromBytes)]
#[repr(u8)]
enum Foo {
A,
}
util_assert_impl_all!(Foo: imp::TryFromBytes);
#[test]
fn test_foo() {
imp::assert_eq!(<Foo as imp::TryFromBytes>::try_read_from_bytes(&[0]), imp::Ok(Foo::A));
imp::assert!(<Foo as imp::TryFromBytes>::try_read_from_bytes(&[]).is_err());
imp::assert!(<Foo as imp::TryFromBytes>::try_read_from_bytes(&[1]).is_err());
imp::assert!(<Foo as imp::TryFromBytes>::try_read_from_bytes(&[0, 0]).is_err());
}
#[derive(Eq, PartialEq, Debug, imp::KnownLayout, imp::Immutable, imp::TryFromBytes)]
#[repr(u16)]
enum Bar {
A = 0,
}
util_assert_impl_all!(Bar: imp::TryFromBytes);
#[test]
fn test_bar() {
imp::assert_eq!(<Bar as imp::TryFromBytes>::try_read_from_bytes(&[0, 0]), imp::Ok(Bar::A));
imp::assert!(<Bar as imp::TryFromBytes>::try_read_from_bytes(&[]).is_err());
imp::assert!(<Bar as imp::TryFromBytes>::try_read_from_bytes(&[0]).is_err());
imp::assert!(<Bar as imp::TryFromBytes>::try_read_from_bytes(&[0, 1]).is_err());
imp::assert!(<Bar as imp::TryFromBytes>::try_read_from_bytes(&[0, 0, 0]).is_err());
}
#[derive(Eq, PartialEq, Debug, imp::KnownLayout, imp::Immutable, imp::TryFromBytes)]
#[repr(u32)]
enum Baz {
A = 1,
B = 0,
}
util_assert_impl_all!(Baz: imp::TryFromBytes);
#[test]
fn test_baz() {
imp::assert_eq!(
<Baz as imp::TryFromBytes>::try_read_from_bytes(imp::IntoBytes::as_bytes(&1u32)),
imp::Ok(Baz::A)
);
imp::assert_eq!(
<Baz as imp::TryFromBytes>::try_read_from_bytes(imp::IntoBytes::as_bytes(&0u32)),
imp::Ok(Baz::B)
);
imp::assert!(<Baz as imp::TryFromBytes>::try_read_from_bytes(&[]).is_err());
imp::assert!(<Baz as imp::TryFromBytes>::try_read_from_bytes(&[0]).is_err());
imp::assert!(<Baz as imp::TryFromBytes>::try_read_from_bytes(&[0, 0]).is_err());
imp::assert!(<Baz as imp::TryFromBytes>::try_read_from_bytes(&[0, 0, 0]).is_err());
imp::assert!(<Baz as imp::TryFromBytes>::try_read_from_bytes(&[0, 0, 0, 0, 0]).is_err());
}
// Test hygiene - make sure that `i8` being shadowed doesn't cause problems for
// the code emitted by the derive.
type i8 = bool;
const THREE: ::core::primitive::i8 = 3;
#[derive(Eq, PartialEq, Debug, imp::KnownLayout, imp::Immutable, imp::TryFromBytes)]
#[repr(i8)]
enum Blah {
A = 1,
B = 0,
C = 1 + 2,
D = 3 + THREE,
}
util_assert_impl_all!(Blah: imp::TryFromBytes);
#[test]
fn test_blah() {
imp::assert_eq!(
<Blah as imp::TryFromBytes>::try_read_from_bytes(imp::IntoBytes::as_bytes(&1i8)),
imp::Ok(Blah::A)
);
imp::assert_eq!(
<Blah as imp::TryFromBytes>::try_read_from_bytes(imp::IntoBytes::as_bytes(&0i8)),
imp::Ok(Blah::B)
);
imp::assert_eq!(
<Blah as imp::TryFromBytes>::try_read_from_bytes(imp::IntoBytes::as_bytes(&3i8)),
imp::Ok(Blah::C)
);
imp::assert_eq!(
<Blah as imp::TryFromBytes>::try_read_from_bytes(imp::IntoBytes::as_bytes(&6i8)),
imp::Ok(Blah::D)
);
imp::assert!(<Blah as imp::TryFromBytes>::try_read_from_bytes(&[]).is_err());
imp::assert!(<Blah as imp::TryFromBytes>::try_read_from_bytes(&[4]).is_err());
imp::assert!(<Blah as imp::TryFromBytes>::try_read_from_bytes(&[0, 0]).is_err());
}
#[derive(
Eq, PartialEq, Debug, imp::KnownLayout, imp::Immutable, imp::TryFromBytes, imp::IntoBytes,
)]
#[repr(C)]
enum FieldlessButNotUnitOnly {
A,
B(),
C {},
}
#[test]
fn test_fieldless_but_not_unit_only() {
const SIZE: usize = ::core::mem::size_of::<FieldlessButNotUnitOnly>();
let disc: [u8; SIZE] = ::zerocopy::transmute!(FieldlessButNotUnitOnly::A);
imp::assert_eq!(
<FieldlessButNotUnitOnly as imp::TryFromBytes>::try_read_from_bytes(&disc[..]),
imp::Ok(FieldlessButNotUnitOnly::A)
);
let disc: [u8; SIZE] = ::zerocopy::transmute!(FieldlessButNotUnitOnly::B());
imp::assert_eq!(
<FieldlessButNotUnitOnly as imp::TryFromBytes>::try_read_from_bytes(&disc[..]),
imp::Ok(FieldlessButNotUnitOnly::B())
);
let disc: [u8; SIZE] = ::zerocopy::transmute!(FieldlessButNotUnitOnly::C {});
imp::assert_eq!(
<FieldlessButNotUnitOnly as imp::TryFromBytes>::try_read_from_bytes(&disc[..]),
imp::Ok(FieldlessButNotUnitOnly::C {})
);
imp::assert!(<FieldlessButNotUnitOnly as imp::TryFromBytes>::try_read_from_bytes(
&[0xFF; SIZE][..]
)
.is_err());
}
#[derive(
Eq, PartialEq, Debug, imp::KnownLayout, imp::Immutable, imp::TryFromBytes, imp::IntoBytes,
)]
#[repr(C)]
enum WeirdDiscriminants {
A = -7,
B,
C = 33,
}
#[test]
fn test_weird_discriminants() {
const SIZE: usize = ::core::mem::size_of::<WeirdDiscriminants>();
let disc: [u8; SIZE] = ::zerocopy::transmute!(WeirdDiscriminants::A);
imp::assert_eq!(
<WeirdDiscriminants as imp::TryFromBytes>::try_read_from_bytes(&disc[..]),
imp::Ok(WeirdDiscriminants::A)
);
let disc: [u8; SIZE] = ::zerocopy::transmute!(WeirdDiscriminants::B);
imp::assert_eq!(
<WeirdDiscriminants as imp::TryFromBytes>::try_read_from_bytes(&disc[..]),
imp::Ok(WeirdDiscriminants::B)
);
let disc: [u8; SIZE] = ::zerocopy::transmute!(WeirdDiscriminants::C);
imp::assert_eq!(
<WeirdDiscriminants as imp::TryFromBytes>::try_read_from_bytes(&disc[..]),
imp::Ok(WeirdDiscriminants::C)
);
imp::assert!(
<WeirdDiscriminants as imp::TryFromBytes>::try_read_from_bytes(&[0xFF; SIZE][..]).is_err()
);
}
// Technically non-portable since this is only `IntoBytes` if the discriminant
// is an `i32` or `u32`, but we'll cross that bridge when we get to it...
#[derive(
Eq, PartialEq, Debug, imp::KnownLayout, imp::Immutable, imp::TryFromBytes, imp::IntoBytes,
)]
#[repr(C)]
enum HasFields {
A(u32),
B { foo: ::core::num::NonZeroU32 },
}
#[test]
fn test_has_fields() {
const SIZE: usize = ::core::mem::size_of::<HasFields>();
let bytes: [u8; SIZE] = ::zerocopy::transmute!(HasFields::A(10));
imp::assert_eq!(
<HasFields as imp::TryFromBytes>::try_read_from_bytes(&bytes[..]),
imp::Ok(HasFields::A(10)),
);
let bytes: [u8; SIZE] =
::zerocopy::transmute!(HasFields::B { foo: ::core::num::NonZeroU32::new(123456).unwrap() });
imp::assert_eq!(
<HasFields as imp::TryFromBytes>::try_read_from_bytes(&bytes[..]),
imp::Ok(HasFields::B { foo: ::core::num::NonZeroU32::new(123456).unwrap() }),
);
}
#[derive(Eq, PartialEq, Debug, imp::KnownLayout, imp::Immutable, imp::TryFromBytes)]
#[repr(C, align(16))]
enum HasFieldsAligned {
A(u32),
B { foo: ::core::num::NonZeroU32 },
}
util_assert_impl_all!(HasFieldsAligned: imp::TryFromBytes);
#[test]
fn test_has_fields_aligned() {
const SIZE: usize = ::core::mem::size_of::<HasFieldsAligned>();
#[derive(imp::IntoBytes)]
#[repr(C)]
struct BytesOfHasFieldsAligned {
has_fields: HasFields,
padding: [u8; 8],
}
let wrap = |has_fields| BytesOfHasFieldsAligned { has_fields, padding: [0; 8] };
let bytes: [u8; SIZE] = ::zerocopy::transmute!(wrap(HasFields::A(10)));
imp::assert_eq!(
<HasFieldsAligned as imp::TryFromBytes>::try_read_from_bytes(&bytes[..]),
imp::Ok(HasFieldsAligned::A(10)),
);
let bytes: [u8; SIZE] = ::zerocopy::transmute!(wrap(HasFields::B {
foo: ::core::num::NonZeroU32::new(123456).unwrap()
}));
imp::assert_eq!(
<HasFieldsAligned as imp::TryFromBytes>::try_read_from_bytes(&bytes[..]),
imp::Ok(HasFieldsAligned::B { foo: ::core::num::NonZeroU32::new(123456).unwrap() }),
);
}
#[derive(
Eq, PartialEq, Debug, imp::KnownLayout, imp::Immutable, imp::TryFromBytes, imp::IntoBytes,
)]
#[repr(u32)]
enum HasFieldsPrimitive {
A(u32),
B { foo: ::core::num::NonZeroU32 },
}
#[test]
fn test_has_fields_primitive() {
const SIZE: usize = ::core::mem::size_of::<HasFieldsPrimitive>();
let bytes: [u8; SIZE] = ::zerocopy::transmute!(HasFieldsPrimitive::A(10));
imp::assert_eq!(
<HasFieldsPrimitive as imp::TryFromBytes>::try_read_from_bytes(&bytes[..]),
imp::Ok(HasFieldsPrimitive::A(10)),
);
let bytes: [u8; SIZE] = ::zerocopy::transmute!(HasFieldsPrimitive::B {
foo: ::core::num::NonZeroU32::new(123456).unwrap(),
});
imp::assert_eq!(
<HasFieldsPrimitive as imp::TryFromBytes>::try_read_from_bytes(&bytes[..]),
imp::Ok(HasFieldsPrimitive::B { foo: ::core::num::NonZeroU32::new(123456).unwrap() }),
);
}
#[derive(Eq, PartialEq, Debug, imp::KnownLayout, imp::Immutable, imp::TryFromBytes)]
#[repr(u32, align(16))]
enum HasFieldsPrimitiveAligned {
A(u32),
B { foo: ::core::num::NonZeroU32 },
}
util_assert_impl_all!(HasFieldsPrimitiveAligned: imp::TryFromBytes);
#[test]
fn test_has_fields_primitive_aligned() {
const SIZE: usize = ::core::mem::size_of::<HasFieldsPrimitiveAligned>();
#[derive(imp::IntoBytes)]
#[repr(C)]
struct BytesOfHasFieldsPrimitiveAligned {
has_fields: HasFieldsPrimitive,
padding: [u8; 8],
}
let wrap = |has_fields| BytesOfHasFieldsPrimitiveAligned { has_fields, padding: [0; 8] };
let bytes: [u8; SIZE] = ::zerocopy::transmute!(wrap(HasFieldsPrimitive::A(10)));
imp::assert_eq!(
<HasFieldsPrimitiveAligned as imp::TryFromBytes>::try_read_from_bytes(&bytes[..]),
imp::Ok(HasFieldsPrimitiveAligned::A(10)),
);
let bytes: [u8; SIZE] = ::zerocopy::transmute!(wrap(HasFieldsPrimitive::B {
foo: ::core::num::NonZeroU32::new(123456).unwrap()
}));
imp::assert_eq!(
<HasFieldsPrimitiveAligned as imp::TryFromBytes>::try_read_from_bytes(&bytes[..]),
imp::Ok(HasFieldsPrimitiveAligned::B {
foo: ::core::num::NonZeroU32::new(123456).unwrap()
}),
);
}
#[derive(imp::TryFromBytes)]
#[repr(align(4), u32)]
enum HasReprAlignFirst {
A,
B,
}
util_assert_impl_all!(HasReprAlignFirst: imp::TryFromBytes);
#[derive(imp::KnownLayout, imp::TryFromBytes, imp::Immutable)]
#[repr(u8)]
enum Complex {
UnitLike,
StructLike { a: u8, b: u16 },
TupleLike(bool, char),
}
util_assert_impl_all!(Complex: imp::TryFromBytes);
#[derive(imp::KnownLayout, imp::TryFromBytes, imp::Immutable)]
#[repr(u8)]
enum ComplexWithGenerics<X, Y> {
UnitLike,
StructLike { a: u8, b: X },
TupleLike(bool, Y),
}
util_assert_impl_all!(ComplexWithGenerics<u16, char>: imp::TryFromBytes);
#[derive(imp::KnownLayout, imp::TryFromBytes, imp::Immutable)]
#[repr(C)]
enum GenericWithLifetimes<'a, 'b, X: 'a, Y: 'b> {
Foo(::core::marker::PhantomData<&'a X>),
Bar(::core::marker::PhantomData<&'b Y>),
}
#[derive(Clone, Copy, imp::TryFromBytes)]
struct A;
#[derive(imp::TryFromBytes)]
#[repr(C)]
enum B {
A(A),
A2 { a: A },
}
#[derive(imp::TryFromBytes)]
#[repr(u8)]
enum FooU8 {
Variant0,
Variant1,
Variant2,
Variant3,
Variant4,
Variant5,
Variant6,
Variant7,
Variant8,
Variant9,
Variant10,
Variant11,
Variant12,
Variant13,
Variant14,
Variant15,
Variant16,
Variant17,
Variant18,
Variant19,
Variant20,
Variant21,
Variant22,
Variant23,
Variant24,
Variant25,
Variant26,
Variant27,
Variant28,
Variant29,
Variant30,
Variant31,
Variant32,
Variant33,
Variant34,
Variant35,
Variant36,
Variant37,
Variant38,
Variant39,
Variant40,
Variant41,
Variant42,
Variant43,
Variant44,
Variant45,
Variant46,
Variant47,
Variant48,
Variant49,
Variant50,
Variant51,
Variant52,
Variant53,
Variant54,
Variant55,
Variant56,
Variant57,
Variant58,
Variant59,
Variant60,
Variant61,
Variant62,
Variant63,
Variant64,
Variant65,
Variant66,
Variant67,
Variant68,
Variant69,
Variant70,
Variant71,
Variant72,
Variant73,
Variant74,
Variant75,
Variant76,
Variant77,
Variant78,
Variant79,
Variant80,
Variant81,
Variant82,
Variant83,
Variant84,
Variant85,
Variant86,
Variant87,
Variant88,
Variant89,
Variant90,
Variant91,
Variant92,
Variant93,
Variant94,
Variant95,
Variant96,
Variant97,
Variant98,
Variant99,
Variant100,
Variant101,
Variant102,
Variant103,
Variant104,
Variant105,
Variant106,
Variant107,
Variant108,
Variant109,
Variant110,
Variant111,
Variant112,
Variant113,
Variant114,
Variant115,
Variant116,
Variant117,
Variant118,
Variant119,
Variant120,
Variant121,
Variant122,
Variant123,
Variant124,
Variant125,
Variant126,
Variant127,
Variant128,
Variant129,
Variant130,
Variant131,
Variant132,
Variant133,
Variant134,
Variant135,
Variant136,
Variant137,
Variant138,
Variant139,
Variant140,
Variant141,
Variant142,
Variant143,
Variant144,
Variant145,
Variant146,
Variant147,
Variant148,
Variant149,
Variant150,
Variant151,
Variant152,
Variant153,
Variant154,
Variant155,
Variant156,
Variant157,
Variant158,
Variant159,
Variant160,
Variant161,
Variant162,
Variant163,
Variant164,
Variant165,
Variant166,
Variant167,
Variant168,
Variant169,
Variant170,
Variant171,
Variant172,
Variant173,
Variant174,
Variant175,
Variant176,
Variant177,
Variant178,
Variant179,
Variant180,
Variant181,
Variant182,
Variant183,
Variant184,
Variant185,
Variant186,
Variant187,
Variant188,
Variant189,
Variant190,
Variant191,
Variant192,
Variant193,
Variant194,
Variant195,
Variant196,
Variant197,
Variant198,
Variant199,
Variant200,
Variant201,
Variant202,
Variant203,
Variant204,
Variant205,
Variant206,
Variant207,
Variant208,
Variant209,
Variant210,
Variant211,
Variant212,
Variant213,
Variant214,
Variant215,
Variant216,
Variant217,
Variant218,
Variant219,
Variant220,
Variant221,
Variant222,
Variant223,
Variant224,
Variant225,
Variant226,
Variant227,
Variant228,
Variant229,
Variant230,
Variant231,
Variant232,
Variant233,
Variant234,
Variant235,
Variant236,
Variant237,
Variant238,
Variant239,
Variant240,
Variant241,
Variant242,
Variant243,
Variant244,
Variant245,
Variant246,
Variant247,
Variant248,
Variant249,
Variant250,
Variant251,
Variant252,
Variant253,
Variant254,
Variant255,
}
#[test]
fn test_trivial_is_bit_valid() {
// Though we don't derive `FromBytes`, `FooU8` *could* soundly implement
// `FromBytes`. Therefore, `TryFromBytes` derive's `is_bit_valid` impl is
// trivial - it unconditionally returns `true`.
util_assert_not_impl_any!(FooU8: imp::FromBytes);
util::test_trivial_is_bit_valid::<FooU8>();
}
#[deny(non_camel_case_types)]
mod issue_2051 {
use super::*;
// Test that the `non_camel_case_types` lint isn't triggered by generated code.
// Prevents regressions of #2051.
#[repr(u32)]
#[derive(imp::TryFromBytes)]
#[allow(non_camel_case_types)]
pub enum Code {
I32_ADD,
I32_SUB,
I32_MUL,
}
}

View File

@@ -0,0 +1,49 @@
// Copyright 2019 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.
// See comment in `include.rs` for why we disable the prelude.
#![no_implicit_prelude]
#![allow(warnings)]
include!("include.rs");
// An enum is `Unaligned` if:
// - No `repr(align(N > 1))`
// - `repr(u8)` or `repr(i8)`
#[derive(imp::Unaligned)]
#[repr(u8)]
enum Foo {
A,
}
util_assert_impl_all!(Foo: imp::Unaligned);
#[derive(imp::Unaligned)]
#[repr(i8)]
enum Bar {
A,
}
util_assert_impl_all!(Bar: imp::Unaligned);
#[derive(imp::Unaligned)]
#[repr(u8, align(1))]
enum Baz {
A,
}
util_assert_impl_all!(Baz: imp::Unaligned);
#[derive(imp::Unaligned)]
#[repr(i8, align(1))]
enum Blah {
B,
}
util_assert_impl_all!(Blah: imp::Unaligned);

33
vendor/zerocopy-derive/tests/eq.rs vendored Normal file
View File

@@ -0,0 +1,33 @@
// Copyright 2024 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.
// See comment in `include.rs` for why we disable the prelude.
#![no_implicit_prelude]
#![allow(warnings)]
include!("include.rs");
#[derive(imp::Debug, imp::IntoBytes, imp::Immutable, imp::ByteEq)]
#[repr(C)]
struct Struct {
a: u64,
b: u32,
c: u32,
}
util_assert_impl_all!(Struct: imp::IntoBytes, imp::PartialEq, imp::Eq);
#[test]
fn test_eq() {
use imp::{assert_eq, assert_ne};
let a = Struct { a: 10, b: 15, c: 20 };
let b = Struct { a: 10, b: 15, c: 25 };
assert_eq!(a, a);
assert_ne!(a, b);
assert_ne!(b, a);
}

38
vendor/zerocopy-derive/tests/hash.rs vendored Normal file
View File

@@ -0,0 +1,38 @@
// Copyright 2024 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.
// See comment in `include.rs` for why we disable the prelude.
#![no_implicit_prelude]
#![allow(warnings)]
include!("include.rs");
#[derive(imp::IntoBytes, imp::Immutable, imp::ByteHash)]
#[repr(C)]
struct Struct {
a: u64,
b: u32,
c: u32,
}
util_assert_impl_all!(Struct: imp::IntoBytes, imp::hash::Hash);
#[test]
fn test_hash() {
use imp::{
hash::{Hash, Hasher},
DefaultHasher,
};
fn hash(val: impl Hash) -> u64 {
let mut hasher = DefaultHasher::new();
val.hash(&mut hasher);
hasher.finish()
}
hash(Struct { a: 10, b: 15, c: 20 });
hash(&[Struct { a: 10, b: 15, c: 20 }, Struct { a: 5, b: 4, c: 3 }]);
}

38
vendor/zerocopy-derive/tests/hygiene.rs vendored Normal file
View File

@@ -0,0 +1,38 @@
// Copyright 2019 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.
// Make sure that macro hygiene will ensure that when we reference "zerocopy",
// that will work properly even if they've renamed the crate and have not
// imported its traits.
// See comment in `include.rs` for why we disable the prelude.
#![no_implicit_prelude]
#![allow(warnings)]
include!("include.rs");
extern crate zerocopy as _zerocopy;
#[derive(_zerocopy::KnownLayout, _zerocopy::FromBytes, _zerocopy::Unaligned)]
#[repr(C)]
struct TypeParams<'a, T, I: imp::Iterator> {
a: T,
c: I::Item,
d: u8,
e: imp::PhantomData<&'a [::core::primitive::u8]>,
f: imp::PhantomData<&'static ::core::primitive::str>,
g: imp::PhantomData<imp::String>,
}
util_assert_impl_all!(
TypeParams<'static, (), imp::IntoIter<()>>:
_zerocopy::KnownLayout,
_zerocopy::FromZeros,
_zerocopy::FromBytes,
_zerocopy::Unaligned
);

129
vendor/zerocopy-derive/tests/include.rs vendored Normal file
View File

@@ -0,0 +1,129 @@
// Copyright 2019 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.
// ON THE PRELUDE: All of the tests in this directory (excepting UI tests)
// disable the prelude via `#![no_implicit_prelude]`. This ensures that all code
// emitted by our derives doesn't accidentally assume that the prelude is
// included, which helps ensure that items are referred to by absolute path,
// which in turn ensures that these items can't accidentally refer to names
// which have been shadowed. For example, the code `x == None` could behave
// incorrectly if, in the scope in which the derive is invoked, `None` has been
// shadowed by `CONST None: Option<usize> = Some(1)`.
//
// `mod imp` allows us to import items and refer to them in this module without
// introducing the risk that this hides bugs in which derive-emitted code uses
// names which are not fully-qualified. For such a bug to manifest, it would
// need to be of the form `imp::Foo`, which is unlikely to happen by accident.
mod imp {
// Since this file is included in every test file, and since not every test
// file uses every item here, we allow unused imports to avoid generating
// warnings.
#[allow(unused)]
pub use {
::core::{
self, assert_eq, assert_ne,
cell::UnsafeCell,
convert::TryFrom,
hash,
marker::PhantomData,
mem::{ManuallyDrop, MaybeUninit},
option::IntoIter,
prelude::v1::*,
primitive::*,
},
::std::{collections::hash_map::DefaultHasher, prelude::v1::*},
::zerocopy::*,
};
}
// These items go in their own module (rather than the top level) for the same
// reason that we use `mod imp` above. See its comment for more details.
pub mod util {
/// A type that doesn't implement any zerocopy traits.
pub struct NotZerocopy<T = ()>(pub T);
/// A `u16` with alignment 2.
///
/// Though `u16` has alignment 2 on some platforms, it's not guaranteed. By
/// contrast, `util::AU16` is guaranteed to have alignment 2.
#[derive(
super::imp::KnownLayout,
super::imp::Immutable,
super::imp::FromBytes,
super::imp::IntoBytes,
Copy,
Clone,
)]
#[repr(C, align(2))]
pub struct AU16(pub u16);
// Since we can't import these by path (ie, `util::assert_impl_all!`), use a
// name prefix to ensure our derive-emitted code isn't accidentally relying
// on `assert_impl_all!` being in scope.
#[macro_export]
macro_rules! util_assert_impl_all {
($type:ty: $($trait:path),+ $(,)?) => {
const _: fn() = || {
use ::core::prelude::v1::*;
::static_assertions::assert_impl_all!($type: $($trait),+);
};
};
}
// Since we can't import these by path (ie, `util::assert_not_impl_any!`),
// use a name prefix to ensure our derive-emitted code isn't accidentally
// relying on `assert_not_impl_any!` being in scope.
#[macro_export]
macro_rules! util_assert_not_impl_any {
($x:ty: $($t:path),+ $(,)?) => {
const _: fn() = || {
use ::core::prelude::v1::*;
::static_assertions::assert_not_impl_any!($x: $($t),+);
};
};
}
#[macro_export]
macro_rules! test_trivial_is_bit_valid {
($x:ty => $name:ident) => {
#[test]
fn $name() {
util::test_trivial_is_bit_valid::<$x>();
}
};
}
// Under some circumstances, our `TryFromBytes` derive generates a trivial
// `is_bit_valid` impl that unconditionally returns `true`. This test
// attempts to validate that this is, indeed, the behavior of our
// `TryFromBytes` derive. It is not foolproof, but is likely to catch some
// mistakes.
//
// As of this writing, this happens when deriving `TryFromBytes` thanks to a
// top-level `#[derive(FromBytes)]`.
pub fn test_trivial_is_bit_valid<T: super::imp::TryFromBytes>() {
// This test works based on the insight that a trivial `is_bit_valid`
// impl should never load any bytes from memory. Thus, while it is
// technically a violation of `is_bit_valid`'s safety precondition to
// pass a pointer to uninitialized memory, the `is_bit_valid` impl we
// expect our derives to generate should never touch this memory, and
// thus should never exhibit UB. By contrast, if our derives are
// spuriously generating non-trivial `is_bit_valid` impls, this should
// cause UB which may be caught by Miri.
let buf = super::imp::MaybeUninit::<T>::uninit();
let ptr = super::imp::Ptr::from_ref(&buf);
// SAFETY: This is intentionally unsound; see the preceding comment.
let ptr = unsafe { ptr.assume_initialized() };
// SAFETY: `T` and `MaybeUninit<T>` have the same layout, so this is a
// size-preserving cast. It is also a provenance-preserving cast.
let ptr = unsafe { ptr.cast_unsized_unchecked(|p| p.cast_sized()) };
assert!(<T as super::imp::TryFromBytes>::is_bit_valid(ptr));
}
}

View File

@@ -0,0 +1,20 @@
// Copyright 2024 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.
// See comment in `include.rs` for why we disable the prelude.
#![no_implicit_prelude]
#![allow(warnings)]
#![forbid(unexpected_cfgs)]
include!("include.rs");
// Make sure no unexpected `cfg`s are emitted by our derives (see #2117).
#[derive(imp::KnownLayout)]
#[repr(C)]
pub struct Test(pub [u8; 32]);

View File

@@ -0,0 +1,40 @@
// Copyright 2019 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.
// See comment in `include.rs` for why we disable the prelude.
#![no_implicit_prelude]
#![allow(warnings)]
include!("include.rs");
// Ensure that types that are use'd and types that are referenced by path work.
mod foo {
use super::*;
#[derive(imp::FromBytes, imp::IntoBytes, imp::Unaligned)]
#[repr(C)]
pub struct Foo {
foo: u8,
}
#[derive(imp::FromBytes, imp::IntoBytes, imp::Unaligned)]
#[repr(C)]
pub struct Bar {
bar: u8,
}
}
use foo::Foo;
#[derive(imp::FromBytes, imp::IntoBytes, imp::Unaligned)]
#[repr(C)]
struct Baz {
foo: Foo,
bar: foo::Bar,
}

View File

@@ -0,0 +1,34 @@
// Copyright 2019 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.
// See comment in `include.rs` for why we disable the prelude.
#![no_implicit_prelude]
#![allow(warnings)]
include!("include.rs");
// FIXME(#847): Make this test succeed on earlier Rust versions.
#[::rustversion::stable(1.59)]
mod test {
use super::*;
// 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(imp::KnownLayout, imp::IntoBytes, imp::FromZeros, imp::FromBytes, imp::Unaligned)]
#[repr(C)]
pub struct Public(Private);
#[derive(imp::KnownLayout, imp::IntoBytes, imp::FromZeros, imp::FromBytes, imp::Unaligned)]
#[repr(C)]
struct Private(());
}

View File

@@ -0,0 +1,77 @@
// Copyright 2019 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.
// See comment in `include.rs` for why we disable the prelude.
#![no_implicit_prelude]
#![allow(warnings)]
include!("include.rs");
// A struct is `FromBytes` if:
// - all fields are `FromBytes`
#[derive(imp::FromBytes)]
struct Zst;
util_assert_impl_all!(Zst: imp::FromBytes);
test_trivial_is_bit_valid!(Zst => test_zst_trivial_is_bit_valid);
#[derive(imp::FromBytes)]
struct One {
a: u8,
}
util_assert_impl_all!(One: imp::FromBytes);
test_trivial_is_bit_valid!(One => test_one_trivial_is_bit_valid);
#[derive(imp::FromBytes)]
struct Two {
a: u8,
b: Zst,
}
util_assert_impl_all!(Two: imp::FromBytes);
test_trivial_is_bit_valid!(Two => test_two_trivial_is_bit_valid);
#[derive(imp::FromBytes)]
struct Unsized {
a: [u8],
}
util_assert_impl_all!(Unsized: imp::FromBytes);
#[derive(imp::FromBytes)]
struct TypeParams<'a, T: ?imp::Sized, I: imp::Iterator> {
a: I::Item,
b: u8,
c: imp::PhantomData<&'a [::core::primitive::u8]>,
d: imp::PhantomData<&'static ::core::primitive::str>,
e: imp::PhantomData<imp::String>,
f: T,
}
util_assert_impl_all!(TypeParams<'static, (), imp::IntoIter<()>>: imp::FromBytes);
util_assert_impl_all!(TypeParams<'static, util::AU16, imp::IntoIter<()>>: imp::FromBytes);
util_assert_impl_all!(TypeParams<'static, [util::AU16], imp::IntoIter<()>>: imp::FromBytes);
test_trivial_is_bit_valid!(TypeParams<'static, (), imp::IntoIter<()>> => test_type_params_trivial_is_bit_valid);
// Deriving `FromBytes` should work if the struct has bounded parameters.
#[derive(imp::FromBytes)]
#[repr(transparent)]
struct WithParams<'a: 'b, 'b: 'a, T: 'a + 'b + imp::FromBytes, const N: usize>(
[T; N],
imp::PhantomData<&'a &'b ()>,
)
where
'a: 'b,
'b: 'a,
T: 'a + 'b + imp::FromBytes;
util_assert_impl_all!(WithParams<'static, 'static, u8, 42>: imp::FromBytes);
test_trivial_is_bit_valid!(WithParams<'static, 'static, u8, 42> => test_with_params_trivial_is_bit_valid);

View File

@@ -0,0 +1,72 @@
// Copyright 2019 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.
// See comment in `include.rs` for why we disable the prelude.
#![no_implicit_prelude]
#![allow(warnings)]
include!("include.rs");
// A struct is `FromZeros` if:
// - all fields are `FromZeros`
#[derive(imp::FromZeros)]
struct Zst;
util_assert_impl_all!(Zst: imp::FromZeros);
#[derive(imp::FromZeros)]
struct One {
a: bool,
}
util_assert_impl_all!(One: imp::FromZeros);
#[derive(imp::FromZeros)]
struct Two {
a: bool,
b: Zst,
}
util_assert_impl_all!(Two: imp::FromZeros);
#[derive(imp::FromZeros)]
struct Unsized {
a: [u8],
}
util_assert_impl_all!(Unsized: imp::FromZeros);
#[derive(imp::FromZeros)]
struct TypeParams<'a, T: ?imp::Sized, I: imp::Iterator> {
a: I::Item,
b: u8,
c: imp::PhantomData<&'a [u8]>,
d: imp::PhantomData<&'static str>,
e: imp::PhantomData<imp::String>,
f: T,
}
util_assert_impl_all!(TypeParams<'static, (), imp::IntoIter<()>>: imp::FromZeros);
util_assert_impl_all!(TypeParams<'static, util::AU16, imp::IntoIter<()>>: imp::FromZeros);
util_assert_impl_all!(TypeParams<'static, [util::AU16], imp::IntoIter<()>>: imp::FromZeros);
// Deriving `FromZeros` should work if the struct has bounded parameters.
#[derive(imp::FromZeros)]
#[repr(transparent)]
struct WithParams<'a: 'b, 'b: 'a, T: 'a + 'b + imp::FromZeros, const N: usize>(
[T; N],
imp::PhantomData<&'a &'b ()>,
)
where
'a: 'b,
'b: 'a,
T: 'a + 'b + imp::FromZeros;
util_assert_impl_all!(WithParams<'static, 'static, u8, 42>: imp::FromZeros);

View File

@@ -0,0 +1,114 @@
// Copyright 2023 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.
// See comment in `include.rs` for why we disable the prelude.
#![no_implicit_prelude]
#![allow(warnings)]
extern crate rustversion;
include!("include.rs");
#[derive(imp::KnownLayout)]
struct Zst;
util_assert_impl_all!(Zst: imp::KnownLayout);
#[derive(imp::KnownLayout)]
struct One {
a: bool,
}
util_assert_impl_all!(One: imp::KnownLayout);
#[derive(imp::KnownLayout)]
struct Two {
a: bool,
b: Zst,
}
util_assert_impl_all!(Two: imp::KnownLayout);
#[derive(imp::KnownLayout)]
struct TypeParams<'a, T, I: imp::Iterator> {
a: I::Item,
b: u8,
c: imp::PhantomData<&'a [::core::primitive::u8]>,
d: imp::PhantomData<&'static ::core::primitive::str>,
e: imp::PhantomData<imp::String>,
f: T,
}
util_assert_impl_all!(TypeParams<'static, (), imp::IntoIter<()>>: imp::KnownLayout);
util_assert_impl_all!(TypeParams<'static, util::AU16, imp::IntoIter<()>>: imp::KnownLayout);
// Deriving `KnownLayout` should work if the struct has bounded parameters.
//
// N.B. We limit this test to rustc >= 1.62, since earlier versions of rustc ICE
// when `KnownLayout` is derived on a `repr(C)` struct whose trailing field
// contains non-static lifetimes.
#[rustversion::since(1.62)]
const _: () = {
#[derive(imp::KnownLayout)]
#[repr(C)]
struct WithParams<'a: 'b, 'b: 'a, T: 'a + 'b + imp::KnownLayout, const N: usize>(
[T; N],
imp::PhantomData<&'a &'b ()>,
)
where
'a: 'b,
'b: 'a,
T: 'a + 'b + imp::KnownLayout;
util_assert_impl_all!(WithParams<'static, 'static, u8, 42>: imp::KnownLayout);
};
const _: () = {
// Similar to the previous test, except that the trailing field contains
// only static lifetimes. This is exercisable on all supported toolchains.
#[derive(imp::KnownLayout)]
#[repr(C)]
struct WithParams<'a: 'b, 'b: 'a, T: 'a + 'b + imp::KnownLayout, const N: usize>(
&'a &'b [T; N],
imp::PhantomData<&'static ()>,
)
where
'a: 'b,
'b: 'a,
T: 'a + 'b + imp::KnownLayout;
util_assert_impl_all!(WithParams<'static, 'static, u8, 42>: imp::KnownLayout);
};
// Deriving `KnownLayout` should work if the struct references `Self`. See
// #2116.
#[derive(imp::KnownLayout)]
#[repr(C)]
struct WithSelfReference {
leading: [u8; Self::N],
trailing: [[u8; Self::N]],
}
impl WithSelfReference {
const N: usize = 42;
}
util_assert_impl_all!(WithSelfReference: imp::KnownLayout);
// Deriving `KnownLayout` should work with generic `repr(packed)` types. See
// #2302.
#[derive(imp::KnownLayout)]
#[repr(C, packed)]
struct Packet<P> {
payload: P,
}
util_assert_impl_all!(Packet<imp::u8>: imp::KnownLayout);

View File

@@ -0,0 +1,97 @@
// Copyright 2023 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.
// See comment in `include.rs` for why we disable the prelude.
#![no_implicit_prelude]
#![allow(warnings)]
include!("include.rs");
#[derive(imp::Immutable)]
struct Zst;
util_assert_impl_all!(Zst: imp::Immutable);
#[derive(imp::Immutable)]
struct One {
a: bool,
}
util_assert_impl_all!(One: imp::Immutable);
#[derive(imp::Immutable)]
struct Two {
a: bool,
b: Zst,
}
util_assert_impl_all!(Two: imp::Immutable);
#[derive(imp::Immutable)]
struct Three {
a: [u8],
}
util_assert_impl_all!(Three: imp::Immutable);
#[derive(imp::Immutable)]
struct Four<'a> {
field: &'a imp::UnsafeCell<u8>,
}
util_assert_impl_all!(Four<'static>: imp::Immutable);
#[derive(imp::Immutable)]
struct TypeParams<'a, T, U, I: imp::Iterator> {
a: I::Item,
b: u8,
c: imp::PhantomData<&'a [::core::primitive::u8]>,
d: imp::PhantomData<&'static ::core::primitive::str>,
e: imp::PhantomData<imp::String>,
f: imp::PhantomData<U>,
g: T,
}
util_assert_impl_all!(TypeParams<'static, (), (), imp::IntoIter<()>>: imp::Immutable);
util_assert_impl_all!(TypeParams<'static, util::AU16, util::AU16, imp::IntoIter<()>>: imp::Immutable);
util_assert_impl_all!(TypeParams<'static, util::AU16, imp::UnsafeCell<u8>, imp::IntoIter<()>>: imp::Immutable);
util_assert_not_impl_any!(TypeParams<'static, imp::UnsafeCell<()>, (), imp::IntoIter<()>>: imp::Immutable);
util_assert_not_impl_any!(TypeParams<'static, [imp::UnsafeCell<u8>; 0], (), imp::IntoIter<()>>: imp::Immutable);
util_assert_not_impl_any!(TypeParams<'static, (), (), imp::IntoIter<imp::UnsafeCell<()>>>: imp::Immutable);
trait Trait {
type Assoc;
}
impl<T> Trait for imp::UnsafeCell<T> {
type Assoc = T;
}
#[derive(imp::Immutable)]
struct WithAssocType<T: Trait> {
field: <T as Trait>::Assoc,
}
util_assert_impl_all!(WithAssocType<imp::UnsafeCell<u8>>: imp::Immutable);
// Deriving `Immutable` should work if the struct has bounded parameters.
#[derive(imp::Immutable)]
#[repr(C)]
struct WithParams<'a: 'b, 'b: 'a, T: 'a + 'b + imp::Immutable, const N: usize>(
[T; N],
imp::PhantomData<&'a &'b ()>,
imp::PhantomData<imp::UnsafeCell<()>>,
&'a imp::UnsafeCell<()>,
)
where
'a: 'b,
'b: 'a,
T: 'a + 'b + imp::Immutable;
util_assert_impl_all!(WithParams<'static, 'static, u8, 42>: imp::Immutable);

View File

@@ -0,0 +1,203 @@
// Copyright 2019 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.
// See comment in `include.rs` for why we disable the prelude.
#![no_implicit_prelude]
#![allow(warnings)]
include!("include.rs");
// A struct is `IntoBytes` if:
// - all fields are `IntoBytes`
// - `repr(C)` or `repr(transparent)` and
// - no padding (size of struct equals sum of size of field types)
// - `repr(packed)`
#[derive(imp::IntoBytes)]
#[repr(C)]
struct CZst;
util_assert_impl_all!(CZst: imp::IntoBytes);
#[derive(imp::IntoBytes)]
#[repr(C)]
struct C {
a: u8,
b: u8,
c: util::AU16,
}
util_assert_impl_all!(C: imp::IntoBytes);
#[derive(imp::IntoBytes)]
#[repr(C)]
struct SyntacticUnsized {
a: u8,
b: u8,
c: [util::AU16],
}
util_assert_impl_all!(C: imp::IntoBytes);
#[derive(imp::IntoBytes)]
#[repr(transparent)]
struct Transparent {
a: u8,
b: CZst,
}
util_assert_impl_all!(Transparent: imp::IntoBytes);
#[derive(imp::IntoBytes)]
#[repr(transparent)]
struct TransparentGeneric<T: ?imp::Sized> {
a: CZst,
b: T,
}
util_assert_impl_all!(TransparentGeneric<u64>: imp::IntoBytes);
util_assert_impl_all!(TransparentGeneric<[u64]>: imp::IntoBytes);
#[derive(imp::IntoBytes)]
#[repr(C, packed)]
struct CZstPacked;
util_assert_impl_all!(CZstPacked: imp::IntoBytes);
#[derive(imp::IntoBytes)]
#[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,
}
util_assert_impl_all!(CPacked: imp::IntoBytes);
#[derive(imp::IntoBytes)]
#[repr(C, packed(2))]
// The same caveats as for CPacked apply - we're assuming u64 is at least
// 4-byte aligned by default. Without packed(2), this should fail, as there
// would be padding between a/b assuming u64 is 4+ byte aligned.
struct CPacked2 {
a: u16,
b: u64,
}
util_assert_impl_all!(CPacked2: imp::IntoBytes);
#[derive(imp::IntoBytes)]
#[repr(C, packed)]
struct CPackedGeneric<T, U: ?imp::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: imp::ManuallyDrop<U>,
}
util_assert_impl_all!(CPackedGeneric<u8, util::AU16>: imp::IntoBytes);
util_assert_impl_all!(CPackedGeneric<u8, [util::AU16]>: imp::IntoBytes);
#[derive(imp::IntoBytes)]
#[repr(packed)]
struct PackedGeneric<T, U: ?imp::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: imp::ManuallyDrop<U>,
}
util_assert_impl_all!(PackedGeneric<u8, util::AU16>: imp::IntoBytes);
util_assert_impl_all!(PackedGeneric<u8, [util::AU16]>: imp::IntoBytes);
// This test is non-portable, but works so long as Rust happens to lay this
// struct out with no padding.
#[derive(imp::IntoBytes)]
struct Unpacked {
a: u8,
b: u8,
}
util_assert_impl_all!(Unpacked: imp::IntoBytes);
#[derive(imp::IntoBytes)]
#[repr(C)]
struct ReprCGenericOneField<T: ?imp::Sized> {
t: T,
}
// Even though `ReprCGenericOneField` has generic type arguments, since it only
// has one field, we don't require that its field types implement `Unaligned`.
util_assert_impl_all!(ReprCGenericOneField<util::AU16>: imp::IntoBytes);
util_assert_impl_all!(ReprCGenericOneField<[util::AU16]>: imp::IntoBytes);
#[derive(imp::IntoBytes)]
#[repr(C)]
struct ReprCGenericMultipleFields<T, U: ?imp::Sized> {
t: T,
u: U,
}
// Since `ReprCGenericMultipleFields` is generic and has more than one field,
// all field types must implement `Unaligned`.
util_assert_impl_all!(ReprCGenericMultipleFields<u8, [u8; 2]>: imp::IntoBytes);
util_assert_impl_all!(ReprCGenericMultipleFields<u8, [[u8; 2]]>: imp::IntoBytes);
util_assert_not_impl_any!(ReprCGenericMultipleFields<u8, util::AU16>: imp::IntoBytes);
util_assert_not_impl_any!(ReprCGenericMultipleFields<u8, [util::AU16]>: imp::IntoBytes);
#[derive(imp::IntoBytes)]
#[repr(transparent)]
struct Unsized {
a: [u8],
}
util_assert_impl_all!(Unsized: imp::IntoBytes);
// Deriving `IntoBytes` should work if the struct has bounded parameters.
#[derive(imp::IntoBytes)]
#[repr(transparent)]
struct WithParams<'a: 'b, 'b: 'a, T: 'a + 'b + imp::IntoBytes, const N: usize>(
[T; N],
imp::PhantomData<&'a &'b ()>,
)
where
'a: 'b,
'b: 'a,
T: 'a + 'b + imp::IntoBytes;
util_assert_impl_all!(WithParams<'static, 'static, u8, 42>: imp::IntoBytes);
// Test for the failure reported in #1182.
#[derive(imp::IntoBytes)]
#[repr(C, packed)]
pub struct IndexEntryFlags(u8);
#[derive(imp::IntoBytes)]
#[repr(C, packed)]
pub struct IndexEntry<const SIZE_BLOCK_ID: usize> {
block_number: imp::native_endian::U64,
flags: IndexEntryFlags,
block_id: [u8; SIZE_BLOCK_ID],
}
util_assert_impl_all!(IndexEntry<0>: imp::IntoBytes);
util_assert_impl_all!(IndexEntry<1>: imp::IntoBytes);

View File

@@ -0,0 +1,259 @@
// Copyright 2023 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.
// See comment in `include.rs` for why we disable the prelude.
#![no_implicit_prelude]
#![allow(warnings)]
include!("include.rs");
// A struct is `imp::TryFromBytes` if:
// - all fields are `imp::TryFromBytes`
#[test]
fn zst() {
// FIXME(#5): Use `try_transmute` in this test once it's available.
let candidate = ::zerocopy::Ptr::from_ref(&());
let candidate = candidate.forget_aligned();
// SAFETY: `&()` trivially consists entirely of initialized bytes.
let candidate = unsafe { candidate.assume_initialized() };
let is_bit_valid = <() as imp::TryFromBytes>::is_bit_valid(candidate);
imp::assert!(is_bit_valid);
}
#[derive(imp::TryFromBytes)]
#[repr(C)]
struct One {
a: u8,
}
util_assert_impl_all!(One: imp::TryFromBytes);
#[test]
fn one() {
// FIXME(#5): Use `try_transmute` in this test once it's available.
let candidate = ::zerocopy::Ptr::from_ref(&One { a: 42 });
let candidate = candidate.forget_aligned();
// SAFETY: `&One` consists entirely of initialized bytes.
let candidate = unsafe { candidate.assume_initialized() };
let is_bit_valid = <One as imp::TryFromBytes>::is_bit_valid(candidate);
imp::assert!(is_bit_valid);
}
#[derive(imp::TryFromBytes)]
#[repr(C)]
struct Two {
a: bool,
b: (),
}
util_assert_impl_all!(Two: imp::TryFromBytes);
#[test]
fn two() {
// FIXME(#5): Use `try_transmute` in this test once it's available.
let candidate = ::zerocopy::Ptr::from_ref(&Two { a: false, b: () });
let candidate = candidate.forget_aligned();
// SAFETY: `&Two` consists entirely of initialized bytes.
let candidate = unsafe { candidate.assume_initialized() };
let is_bit_valid = <Two as imp::TryFromBytes>::is_bit_valid(candidate);
imp::assert!(is_bit_valid);
}
#[test]
fn two_bad() {
// FIXME(#5): Use `try_transmute` in this test once it's available.
let candidate = ::zerocopy::Ptr::from_ref(&[2u8][..]);
let candidate = candidate.forget_aligned();
// SAFETY: `&Two` consists entirely of initialized bytes.
let candidate = unsafe { candidate.assume_initialized() };
// SAFETY:
// - The cast preserves address and size. As a result, the cast will address
// the same bytes as `c`.
// - The cast preserves provenance.
// - Neither the input nor output types contain any `UnsafeCell`s.
let candidate = unsafe { candidate.cast_unsized_unchecked(|p| p.cast::<Two>()) };
// SAFETY: `candidate`'s referent is as-initialized as `Two`.
let candidate = unsafe { candidate.assume_initialized() };
let is_bit_valid = <Two as imp::TryFromBytes>::is_bit_valid(candidate);
imp::assert!(!is_bit_valid);
}
#[derive(imp::TryFromBytes)]
#[repr(C)]
struct Unsized {
a: [u8],
}
util_assert_impl_all!(Unsized: imp::TryFromBytes);
#[test]
fn un_sized() {
// FIXME(#5): Use `try_transmute` in this test once it's available.
let candidate = ::zerocopy::Ptr::from_ref(&[16, 12, 42][..]);
let candidate = candidate.forget_aligned();
// SAFETY: `&Unsized` consists entirely of initialized bytes.
let candidate = unsafe { candidate.assume_initialized() };
// SAFETY:
// - The cast preserves address and size. As a result, the cast will address
// the same bytes as `c`.
// - The cast preserves provenance.
// - Neither the input nor output types contain any `UnsafeCell`s.
let candidate = unsafe {
candidate.cast_unsized_unchecked(|p| {
let ptr =
imp::core::ptr::NonNull::new_unchecked(p.as_non_null().as_ptr() as *mut Unsized);
::zerocopy::pointer::PtrInner::new(ptr)
})
};
// SAFETY: `candidate`'s referent is as-initialized as `Two`.
let candidate = unsafe { candidate.assume_initialized() };
let is_bit_valid = <Unsized as imp::TryFromBytes>::is_bit_valid(candidate);
imp::assert!(is_bit_valid);
}
#[derive(imp::TryFromBytes)]
#[repr(C)]
struct TypeParams<'a, T: ?imp::Sized, I: imp::Iterator> {
a: I::Item,
b: u8,
c: imp::PhantomData<&'a [u8]>,
d: imp::PhantomData<&'static str>,
e: imp::PhantomData<imp::String>,
f: T,
}
util_assert_impl_all!(TypeParams<'static, (), imp::IntoIter<()>>: imp::TryFromBytes);
util_assert_impl_all!(TypeParams<'static, util::AU16, imp::IntoIter<()>>: imp::TryFromBytes);
util_assert_impl_all!(TypeParams<'static, [util::AU16], imp::IntoIter<()>>: imp::TryFromBytes);
// Deriving `imp::TryFromBytes` should work if the struct has bounded parameters.
#[derive(imp::TryFromBytes)]
#[repr(transparent)]
struct WithParams<'a: 'b, 'b: 'a, T: 'a + 'b + imp::TryFromBytes, const N: usize>(
imp::PhantomData<&'a &'b ()>,
[T],
)
where
'a: 'b,
'b: 'a,
T: 'a + 'b + imp::TryFromBytes;
util_assert_impl_all!(WithParams<'static, 'static, u8, 42>: imp::TryFromBytes);
#[derive(imp::FromBytes)]
#[repr(C)]
struct MaybeFromBytes<T>(T);
#[test]
fn test_maybe_from_bytes() {
// When deriving `FromBytes` on a type with no generic parameters, we emit a
// trivial `is_bit_valid` impl that always returns true. This test confirms
// that we *don't* spuriously do that when generic parameters are present.
let candidate = ::zerocopy::Ptr::from_ref(&[2u8][..]);
let candidate = candidate.bikeshed_recall_initialized_from_bytes();
// SAFETY:
// - The cast preserves address and size. As a result, the cast will address
// the same bytes as `c`.
// - The cast preserves provenance.
// - Neither the input nor output types contain any `UnsafeCell`s.
let candidate =
unsafe { candidate.cast_unsized_unchecked(|p| p.cast::<MaybeFromBytes<bool>>()) };
// SAFETY: `[u8]` consists entirely of initialized bytes.
let candidate = unsafe { candidate.assume_initialized() };
let is_bit_valid = <MaybeFromBytes<bool> as imp::TryFromBytes>::is_bit_valid(candidate);
imp::assert!(!is_bit_valid);
}
#[derive(Debug, PartialEq, Eq, imp::TryFromBytes, imp::Immutable, imp::KnownLayout)]
#[repr(C, packed)]
struct CPacked {
a: u8,
// NOTE: The `u32` type is not guaranteed to have alignment 4, although it
// does on many platforms. However, to fix this would require a custom type
// with a `#[repr(align(4))]` attribute, and `#[repr(packed)]` types are not
// allowed to transitively contain `#[repr(align(...))]` types. Thus, we
// have no choice but to use `u32` here. Luckily, these tests run in CI on
// platforms on which `u32` has alignment 4, so this isn't that big of a
// deal.
b: u32,
}
#[test]
fn c_packed() {
let candidate = &[42u8, 0xFF, 0xFF, 0xFF, 0xFF];
let converted = <CPacked as imp::TryFromBytes>::try_ref_from_bytes(candidate);
imp::assert_eq!(converted, imp::Ok(&CPacked { a: 42, b: u32::MAX }));
}
#[derive(imp::TryFromBytes, imp::KnownLayout, imp::Immutable)]
#[repr(C, packed)]
struct CPackedUnsized {
a: u8,
// NOTE: The `u32` type is not guaranteed to have alignment 4, although it
// does on many platforms. However, to fix this would require a custom type
// with a `#[repr(align(4))]` attribute, and `#[repr(packed)]` types are not
// allowed to transitively contain `#[repr(align(...))]` types. Thus, we
// have no choice but to use `u32` here. Luckily, these tests run in CI on
// platforms on which `u32` has alignment 4, so this isn't that big of a
// deal.
b: [u32],
}
#[test]
fn c_packed_unsized() {
let candidate = &[42u8, 0xFF, 0xFF, 0xFF, 0xFF];
let converted = <CPackedUnsized as imp::TryFromBytes>::try_ref_from_bytes(candidate);
imp::assert!(converted.is_ok());
}
#[derive(imp::TryFromBytes)]
#[repr(packed)]
struct PackedUnsized {
a: u8,
// NOTE: The `u32` type is not guaranteed to have alignment 4, although it
// does on many platforms. However, to fix this would require a custom type
// with a `#[repr(align(4))]` attribute, and `#[repr(packed)]` types are not
// allowed to transitively contain `#[repr(align(...))]` types. Thus, we
// have no choice but to use `u32` here. Luckily, these tests run in CI on
// platforms on which `u32` has alignment 4, so this isn't that big of a
// deal.
b: [u32],
}
#[test]
fn packed_unsized() {
let candidate = &[42u8, 0xFF, 0xFF, 0xFF, 0xFF];
let converted = <CPackedUnsized as imp::TryFromBytes>::try_ref_from_bytes(candidate);
imp::assert!(converted.is_ok());
let candidate = &[42u8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF];
let converted = <CPackedUnsized as imp::TryFromBytes>::try_ref_from_bytes(candidate);
imp::assert!(converted.is_err());
let candidate = &[42u8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF];
let converted = <CPackedUnsized as imp::TryFromBytes>::try_ref_from_bytes(candidate);
imp::assert!(converted.is_ok());
}
#[derive(imp::TryFromBytes)]
struct A;
#[derive(imp::TryFromBytes)]
struct B {
a: A,
}

View File

@@ -0,0 +1,96 @@
// Copyright 2019 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.
// See comment in `include.rs` for why we disable the prelude.
#![no_implicit_prelude]
#![allow(warnings)]
include!("include.rs");
// A struct is `Unaligned` if:
// - `repr(align)` is no more than 1 and either
// - `repr(C)` or `repr(transparent)` and
// - all fields Unaligned
// - `repr(packed)`
#[derive(imp::Unaligned)]
#[repr(C)]
struct Foo {
a: u8,
}
util_assert_impl_all!(Foo: imp::Unaligned);
#[derive(imp::Unaligned)]
#[repr(transparent)]
struct Bar {
a: u8,
}
util_assert_impl_all!(Bar: imp::Unaligned);
#[derive(imp::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,
}
util_assert_impl_all!(Baz: imp::Unaligned);
#[derive(imp::Unaligned)]
#[repr(C, align(1))]
struct FooAlign {
a: u8,
}
util_assert_impl_all!(FooAlign: imp::Unaligned);
#[derive(imp::Unaligned)]
#[repr(transparent)]
struct Unsized {
a: [u8],
}
util_assert_impl_all!(Unsized: imp::Unaligned);
#[derive(imp::Unaligned)]
#[repr(C)]
struct TypeParams<'a, T: ?imp::Sized, I: imp::Iterator> {
a: I::Item,
b: u8,
c: imp::PhantomData<&'a [::core::primitive::u8]>,
d: imp::PhantomData<&'static ::core::primitive::str>,
e: imp::PhantomData<imp::String>,
f: T,
}
util_assert_impl_all!(TypeParams<'static, (), imp::IntoIter<()>>: imp::Unaligned);
util_assert_impl_all!(TypeParams<'static, ::core::primitive::u8, imp::IntoIter<()>>: imp::Unaligned);
util_assert_impl_all!(TypeParams<'static, [::core::primitive::u8], imp::IntoIter<()>>: imp::Unaligned);
// Deriving `Unaligned` should work if the struct has bounded parameters.
#[derive(imp::Unaligned)]
#[repr(transparent)]
struct WithParams<'a: 'b, 'b: 'a, T: 'a + 'b + imp::Unaligned, const N: usize>(
[T; N],
imp::PhantomData<&'a &'b ()>,
)
where
'a: 'b,
'b: 'a,
T: 'a + 'b + imp::Unaligned;
util_assert_impl_all!(WithParams<'static, 'static, u8, 42>: imp::Unaligned);

View File

@@ -0,0 +1,60 @@
// Copyright 2019 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.
#![allow(clippy::uninlined_format_args)]
use std::env;
use testutil::set_rustflags_w_warnings;
fn test(subdir: &str) {
let version = testutil::ToolchainVersion::extract_from_pwd().unwrap();
// See the doc comment on this method for an explanation of what this does
// and why we store source files in different directories.
let source_files_dirname = version.get_ui_source_files_dirname_and_maybe_print_warning();
// Set `-Wwarnings` in the `RUSTFLAGS` environment variable to ensure that
// `.stderr` files reflect what the typical user would encounter.
set_rustflags_w_warnings();
let t = trybuild::TestCases::new();
t.compile_fail(format!("tests/{}/{}/*.rs", source_files_dirname, subdir));
}
#[test]
#[cfg_attr(miri, ignore)]
fn ui() {
test("");
// This tests the behavior when `--cfg zerocopy_derive_union_into_bytes` is
// not present, so remove it. If this logic is wrong, that's fine - it will
// exhibit as a test failure that we can debug at that point.
let rustflags = env::var("RUSTFLAGS").unwrap();
let new_rustflags = rustflags.replace("--cfg zerocopy_derive_union_into_bytes", "");
// SAFETY: None of our code is concurrently accessinv env vars. It's
// possible that the test framework has spawned other threads that are
// concurrently accessing env vars, but we can't do anything about that.
#[allow(unused_unsafe)] // `set_var` is safe on our MSRV.
unsafe {
env::set_var("RUSTFLAGS", new_rustflags)
};
test("union_into_bytes_cfg");
// Reset RUSTFLAGS in case we later add other tests which rely on its value.
// This isn't strictly necessary, but it's easier to add this now when we're
// thinking about the semantics of these env vars than to debug later when
// we've forgotten about it.
//
// SAFETY: See previous safety comment.
#[allow(unused_unsafe)] // `set_var` is safe on our MSRV.
unsafe {
env::set_var("RUSTFLAGS", rustflags)
};
}

View File

@@ -0,0 +1,38 @@
// Copyright 2019 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.
extern crate zerocopy;
#[path = "../include.rs"]
mod util;
use core::marker::PhantomData;
use zerocopy::{FromBytes, FromZeros, IntoBytes, TryFromBytes, Unaligned};
use self::util::util::NotZerocopy;
fn main() {}
// Test generic transparent structs
#[derive(IntoBytes, 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.
util_assert_impl_all!(TransparentStruct<NotZerocopy>: TryFromBytes);
util_assert_impl_all!(TransparentStruct<NotZerocopy>: FromZeros);
util_assert_impl_all!(TransparentStruct<NotZerocopy>: FromBytes);
util_assert_impl_all!(TransparentStruct<NotZerocopy>: IntoBytes);
util_assert_impl_all!(TransparentStruct<NotZerocopy>: Unaligned);

View File

@@ -0,0 +1,89 @@
error[E0277]: the trait bound `NotZerocopy: zerocopy::TryFromBytes` is not satisfied
--> tests/ui-msrv/derive_transparent.rs:34:1
|
34 | util_assert_impl_all!(TransparentStruct<NotZerocopy>: TryFromBytes);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `zerocopy::TryFromBytes` is not implemented for `NotZerocopy`
|
note: required because of the requirements on the impl of `zerocopy::TryFromBytes` for `TransparentStruct<NotZerocopy>`
--> tests/ui-msrv/derive_transparent.rs:24:21
|
24 | #[derive(IntoBytes, FromBytes, Unaligned)]
| ^^^^^^^^^
note: required by a bound in `_::{closure#0}::_::{closure#0}::assert_impl_all`
--> tests/ui-msrv/derive_transparent.rs:34:1
|
34 | util_assert_impl_all!(TransparentStruct<NotZerocopy>: TryFromBytes);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `_::{closure#0}::_::{closure#0}::assert_impl_all`
= note: this error originates in the macro `::static_assertions::assert_impl_all` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `NotZerocopy: FromZeros` is not satisfied
--> tests/ui-msrv/derive_transparent.rs:35:1
|
35 | util_assert_impl_all!(TransparentStruct<NotZerocopy>: FromZeros);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `FromZeros` is not implemented for `NotZerocopy`
|
note: required because of the requirements on the impl of `FromZeros` for `TransparentStruct<NotZerocopy>`
--> tests/ui-msrv/derive_transparent.rs:24:21
|
24 | #[derive(IntoBytes, FromBytes, Unaligned)]
| ^^^^^^^^^
note: required by a bound in `_::{closure#0}::_::{closure#0}::assert_impl_all`
--> tests/ui-msrv/derive_transparent.rs:35:1
|
35 | util_assert_impl_all!(TransparentStruct<NotZerocopy>: FromZeros);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `_::{closure#0}::_::{closure#0}::assert_impl_all`
= note: this error originates in the macro `::static_assertions::assert_impl_all` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `NotZerocopy: zerocopy::FromBytes` is not satisfied
--> tests/ui-msrv/derive_transparent.rs:36:1
|
36 | util_assert_impl_all!(TransparentStruct<NotZerocopy>: FromBytes);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `zerocopy::FromBytes` is not implemented for `NotZerocopy`
|
note: required because of the requirements on the impl of `zerocopy::FromBytes` for `TransparentStruct<NotZerocopy>`
--> tests/ui-msrv/derive_transparent.rs:24:21
|
24 | #[derive(IntoBytes, FromBytes, Unaligned)]
| ^^^^^^^^^
note: required by a bound in `_::{closure#0}::_::{closure#0}::assert_impl_all`
--> tests/ui-msrv/derive_transparent.rs:36:1
|
36 | util_assert_impl_all!(TransparentStruct<NotZerocopy>: FromBytes);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `_::{closure#0}::_::{closure#0}::assert_impl_all`
= note: this error originates in the macro `::static_assertions::assert_impl_all` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `NotZerocopy: zerocopy::IntoBytes` is not satisfied
--> tests/ui-msrv/derive_transparent.rs:37:1
|
37 | util_assert_impl_all!(TransparentStruct<NotZerocopy>: IntoBytes);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `zerocopy::IntoBytes` is not implemented for `NotZerocopy`
|
note: required because of the requirements on the impl of `zerocopy::IntoBytes` for `TransparentStruct<NotZerocopy>`
--> tests/ui-msrv/derive_transparent.rs:24:10
|
24 | #[derive(IntoBytes, FromBytes, Unaligned)]
| ^^^^^^^^^
note: required by a bound in `_::{closure#0}::_::{closure#0}::assert_impl_all`
--> tests/ui-msrv/derive_transparent.rs:37:1
|
37 | util_assert_impl_all!(TransparentStruct<NotZerocopy>: IntoBytes);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `_::{closure#0}::_::{closure#0}::assert_impl_all`
= note: this error originates in the macro `::static_assertions::assert_impl_all` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `NotZerocopy: zerocopy::Unaligned` is not satisfied
--> tests/ui-msrv/derive_transparent.rs:38:1
|
38 | util_assert_impl_all!(TransparentStruct<NotZerocopy>: Unaligned);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `zerocopy::Unaligned` is not implemented for `NotZerocopy`
|
note: required because of the requirements on the impl of `zerocopy::Unaligned` for `TransparentStruct<NotZerocopy>`
--> tests/ui-msrv/derive_transparent.rs:24:32
|
24 | #[derive(IntoBytes, FromBytes, Unaligned)]
| ^^^^^^^^^
note: required by a bound in `_::{closure#0}::_::{closure#0}::assert_impl_all`
--> tests/ui-msrv/derive_transparent.rs:38:1
|
38 | util_assert_impl_all!(TransparentStruct<NotZerocopy>: Unaligned);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `_::{closure#0}::_::{closure#0}::assert_impl_all`
= note: this error originates in the macro `::static_assertions::assert_impl_all` (in Nightly builds, run with -Z macro-backtrace for more info)

View File

@@ -0,0 +1,577 @@
// Copyright 2019 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.
#[macro_use]
extern crate zerocopy;
fn main() {}
//
// Generic errors
//
#[derive(FromBytes)]
#[repr("foo")]
enum Generic1 {
A,
}
#[derive(FromBytes)]
#[repr(foo)]
enum Generic2 {
A,
}
#[derive(FromBytes)]
#[repr(transparent)]
enum Generic3 {
A,
}
#[derive(FromBytes)]
#[repr(u8, u16)]
enum Generic4 {
A,
}
#[derive(FromBytes)]
enum Generic5 {
A,
}
//
// Immutable errors
//
#[derive(Immutable)]
enum Immutable1 {
A(core::cell::UnsafeCell<()>),
}
#[derive(Immutable)]
enum Never {}
#[derive(Immutable)]
enum Immutable2 {
Uninhabited(Never, core::cell::UnsafeCell<u8>),
Inhabited(u8),
}
//
// TryFromBytes errors
//
#[derive(TryFromBytes)]
enum TryFromBytes1 {
A,
}
#[derive(TryFromBytes)]
enum TryFromBytes2 {
A,
B(u8),
}
struct NotTryFromBytes;
#[derive(TryFromBytes)]
#[repr(u8)]
enum TryFromBytes3 {
A(NotTryFromBytes),
}
//
// FromZeros errors
//
#[derive(FromZeros)]
enum FromZeros1 {
A(u8),
}
#[derive(FromZeros)]
enum FromZeros2 {
A,
B(u8),
}
#[derive(FromZeros)]
enum FromZeros3 {
A = 1,
B,
}
#[derive(FromZeros)]
#[repr(u8)]
enum FromZeros4 {
A = 1,
B = 2,
}
const NEGATIVE_ONE: i8 = -1;
#[derive(FromZeros)]
#[repr(i8)]
enum FromZeros5 {
A = NEGATIVE_ONE,
B,
}
struct NotFromZeros;
#[derive(FromZeros)]
#[repr(u8)]
enum FromZeros6 {
A(NotFromZeros),
}
#[derive(FromZeros)]
#[repr(u8)]
enum FromZeros7 {
A = 1,
B(NotFromZeros),
}
//
// FromBytes errors
//
#[derive(FromBytes)]
enum FromBytes1 {
A,
}
#[derive(FromBytes)]
#[repr(C)]
enum FromBytes2 {
A,
}
#[derive(FromBytes)]
#[repr(usize)]
enum FromBytes3 {
A,
}
#[derive(FromBytes)]
#[repr(isize)]
enum FromBytes4 {
A,
}
#[derive(FromBytes)]
#[repr(u32)]
enum FromBytes5 {
A,
}
#[derive(FromBytes)]
#[repr(i32)]
enum FromBytes6 {
A,
}
#[derive(FromBytes)]
#[repr(u64)]
enum FromBytes7 {
A,
}
#[derive(FromBytes)]
#[repr(i64)]
enum FromBytes8 {
A,
}
#[derive(FromBytes)]
#[repr(u8)]
enum FooU8 {
Variant0,
Variant1,
Variant2,
Variant3,
Variant4,
Variant5,
Variant6,
Variant7,
Variant8,
Variant9,
Variant10,
Variant11,
Variant12,
Variant13,
Variant14,
Variant15,
Variant16,
Variant17,
Variant18,
Variant19,
Variant20,
Variant21,
Variant22,
Variant23,
Variant24,
Variant25,
Variant26,
Variant27,
Variant28,
Variant29,
Variant30,
Variant31,
Variant32,
Variant33,
Variant34,
Variant35,
Variant36,
Variant37,
Variant38,
Variant39,
Variant40,
Variant41,
Variant42,
Variant43,
Variant44,
Variant45,
Variant46,
Variant47,
Variant48,
Variant49,
Variant50,
Variant51,
Variant52,
Variant53,
Variant54,
Variant55,
Variant56,
Variant57,
Variant58,
Variant59,
Variant60,
Variant61,
Variant62,
Variant63,
Variant64,
Variant65,
Variant66,
Variant67,
Variant68,
Variant69,
Variant70,
Variant71,
Variant72,
Variant73,
Variant74,
Variant75,
Variant76,
Variant77,
Variant78,
Variant79,
Variant80,
Variant81,
Variant82,
Variant83,
Variant84,
Variant85,
Variant86,
Variant87,
Variant88,
Variant89,
Variant90,
Variant91,
Variant92,
Variant93,
Variant94,
Variant95,
Variant96,
Variant97,
Variant98,
Variant99,
Variant100,
Variant101,
Variant102,
Variant103,
Variant104,
Variant105,
Variant106,
Variant107,
Variant108,
Variant109,
Variant110,
Variant111,
Variant112,
Variant113,
Variant114,
Variant115,
Variant116,
Variant117,
Variant118,
Variant119,
Variant120,
Variant121,
Variant122,
Variant123,
Variant124,
Variant125,
Variant126,
Variant127,
Variant128,
Variant129,
Variant130,
Variant131,
Variant132,
Variant133,
Variant134,
Variant135,
Variant136,
Variant137,
Variant138,
Variant139,
Variant140,
Variant141,
Variant142,
Variant143,
Variant144,
Variant145,
Variant146,
Variant147,
Variant148,
Variant149,
Variant150,
Variant151,
Variant152,
Variant153,
Variant154,
Variant155,
Variant156,
Variant157,
Variant158,
Variant159,
Variant160,
Variant161,
Variant162,
Variant163,
Variant164,
Variant165,
Variant166,
Variant167,
Variant168,
Variant169,
Variant170,
Variant171,
Variant172,
Variant173,
Variant174,
Variant175,
Variant176,
Variant177,
Variant178,
Variant179,
Variant180,
Variant181,
Variant182,
Variant183,
Variant184,
Variant185,
Variant186,
Variant187,
Variant188,
Variant189,
Variant190,
Variant191,
Variant192,
Variant193,
Variant194,
Variant195,
Variant196,
Variant197,
Variant198,
Variant199,
Variant200,
Variant201,
Variant202,
Variant203,
Variant204,
Variant205,
Variant206,
Variant207,
Variant208,
Variant209,
Variant210,
Variant211,
Variant212,
Variant213,
Variant214,
Variant215,
Variant216,
Variant217,
Variant218,
Variant219,
Variant220,
Variant221,
Variant222,
Variant223,
Variant224,
Variant225,
Variant226,
Variant227,
Variant228,
Variant229,
Variant230,
Variant231,
Variant232,
Variant233,
Variant234,
Variant235,
Variant236,
Variant237,
Variant238,
Variant239,
Variant240,
Variant241,
Variant242,
Variant243,
Variant244,
Variant245,
Variant246,
Variant247,
Variant248,
Variant249,
Variant250,
Variant251,
Variant252,
Variant253,
Variant254,
Variant255(bool),
}
//
// Unaligned errors
//
#[derive(Unaligned)]
#[repr(C)]
enum Unaligned1 {
A,
}
#[derive(Unaligned)]
#[repr(u16)]
enum Unaligned2 {
A,
}
#[derive(Unaligned)]
#[repr(i16)]
enum Unaligned3 {
A,
}
#[derive(Unaligned)]
#[repr(u32)]
enum Unaligned4 {
A,
}
#[derive(Unaligned)]
#[repr(i32)]
enum Unaligned5 {
A,
}
#[derive(Unaligned)]
#[repr(u64)]
enum Unaligned6 {
A,
}
#[derive(Unaligned)]
#[repr(i64)]
enum Unaligned7 {
A,
}
#[derive(Unaligned)]
#[repr(usize)]
enum Unaligned8 {
A,
}
#[derive(Unaligned)]
#[repr(isize)]
enum Unaligned9 {
A,
}
#[derive(Unaligned)]
#[repr(u8, align(2))]
enum Unaligned10 {
A,
}
#[derive(Unaligned)]
#[repr(i8, align(2))]
enum Unaligned11 {
A,
}
#[derive(Unaligned)]
#[repr(align(1), align(2))]
enum Unaligned12 {
A,
}
#[derive(Unaligned)]
#[repr(align(2), align(4))]
enum Unaligned13 {
A,
}
//
// IntoBytes errors
//
#[derive(IntoBytes)]
#[repr(u8)]
enum IntoBytes1 {
A,
B(u8),
}
#[derive(IntoBytes)]
#[repr(C, align(4))]
struct Align4IntoBytes(u32);
#[derive(IntoBytes)]
#[repr(u8)]
enum IntoBytes2 {
A(Align4IntoBytes),
}
#[derive(IntoBytes)]
#[repr(u32)]
enum IntoBytes3 {
A(u32),
B(u16),
}
#[derive(IntoBytes)]
enum IntoBytes4 {
A(u32),
B(u16),
}
#[derive(IntoBytes)]
enum IntoBytes5 {
A(u32),
}
#[derive(IntoBytes)]
#[repr(u8)]
enum IntoBytes6<T> {
A(T),
}

View File

@@ -0,0 +1,406 @@
error: unrecognized representation hint
--> tests/ui-msrv/enum.rs:19:8
|
19 | #[repr("foo")]
| ^^^^^
error: unrecognized representation hint
--> tests/ui-msrv/enum.rs:25:8
|
25 | #[repr(foo)]
| ^^^
error: must have #[repr(C)] or #[repr(Int)] attribute in order to guarantee this type's memory layout
--> tests/ui-msrv/enum.rs:30:10
|
30 | #[derive(FromBytes)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `FromBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error: this conflicts with another representation hint
--> tests/ui-msrv/enum.rs:37:12
|
37 | #[repr(u8, u16)]
| ^^^
error: must have #[repr(C)] or #[repr(Int)] attribute in order to guarantee this type's memory layout
--> tests/ui-msrv/enum.rs:42:10
|
42 | #[derive(FromBytes)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `FromBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error: must have #[repr(C)] or #[repr(Int)] attribute in order to guarantee this type's memory layout
--> tests/ui-msrv/enum.rs:69:10
|
69 | #[derive(TryFromBytes)]
| ^^^^^^^^^^^^
|
= note: this error originates in the derive macro `TryFromBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error: must have #[repr(C)] or #[repr(Int)] attribute in order to guarantee this type's memory layout
--> tests/ui-msrv/enum.rs:74:10
|
74 | #[derive(TryFromBytes)]
| ^^^^^^^^^^^^
|
= note: this error originates in the derive macro `TryFromBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error: must have #[repr(C)] or #[repr(Int)] attribute in order to guarantee this type's memory layout
--> tests/ui-msrv/enum.rs:92:10
|
92 | #[derive(FromZeros)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `FromZeros` (in Nightly builds, run with -Z macro-backtrace for more info)
error: must have #[repr(C)] or #[repr(Int)] attribute in order to guarantee this type's memory layout
--> tests/ui-msrv/enum.rs:97:10
|
97 | #[derive(FromZeros)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `FromZeros` (in Nightly builds, run with -Z macro-backtrace for more info)
error: must have #[repr(C)] or #[repr(Int)] attribute in order to guarantee this type's memory layout
--> tests/ui-msrv/enum.rs:103:10
|
103 | #[derive(FromZeros)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `FromZeros` (in Nightly builds, run with -Z macro-backtrace for more info)
error: FromZeros only supported on enums with a variant that has a discriminant of `0`
--> tests/ui-msrv/enum.rs:110:1
|
110 | / #[repr(u8)]
111 | | enum FromZeros4 {
112 | | A = 1,
113 | | B = 2,
114 | | }
| |_^
error: FromZeros only supported on enums with a variant that has a discriminant of `0`
help: This enum has discriminants which are not literal integers. One of those may define or imply which variant has a discriminant of zero. Use a literal integer to define or imply the variant with a discriminant of zero.
--> tests/ui-msrv/enum.rs:119:1
|
119 | / #[repr(i8)]
120 | | enum FromZeros5 {
121 | | A = NEGATIVE_ONE,
122 | | B,
123 | | }
| |_^
error: FromZeros only supported on enums with a variant that has a discriminant of `0`
--> tests/ui-msrv/enum.rs:134:1
|
134 | / #[repr(u8)]
135 | | enum FromZeros7 {
136 | | A = 1,
137 | | B(NotFromZeros),
138 | | }
| |_^
error: must have #[repr(C)] or #[repr(Int)] attribute in order to guarantee this type's memory layout
--> tests/ui-msrv/enum.rs:144:10
|
144 | #[derive(FromBytes)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `FromBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error: `FromBytes` only supported on enums with `#[repr(...)]` attributes `u8`, `i8`, `u16`, or `i16`
--> tests/ui-msrv/enum.rs:150:8
|
150 | #[repr(C)]
| ^
error: `FromBytes` only supported on enums with `#[repr(...)]` attributes `u8`, `i8`, `u16`, or `i16`
--> tests/ui-msrv/enum.rs:156:8
|
156 | #[repr(usize)]
| ^^^^^
error: `FromBytes` only supported on enums with `#[repr(...)]` attributes `u8`, `i8`, `u16`, or `i16`
--> tests/ui-msrv/enum.rs:162:8
|
162 | #[repr(isize)]
| ^^^^^
error: `FromBytes` only supported on enums with `#[repr(...)]` attributes `u8`, `i8`, `u16`, or `i16`
--> tests/ui-msrv/enum.rs:168:8
|
168 | #[repr(u32)]
| ^^^
error: `FromBytes` only supported on enums with `#[repr(...)]` attributes `u8`, `i8`, `u16`, or `i16`
--> tests/ui-msrv/enum.rs:174:8
|
174 | #[repr(i32)]
| ^^^
error: `FromBytes` only supported on enums with `#[repr(...)]` attributes `u8`, `i8`, `u16`, or `i16`
--> tests/ui-msrv/enum.rs:180:8
|
180 | #[repr(u64)]
| ^^^
error: `FromBytes` only supported on enums with `#[repr(...)]` attributes `u8`, `i8`, `u16`, or `i16`
--> tests/ui-msrv/enum.rs:186:8
|
186 | #[repr(i64)]
| ^^^
error: must have #[repr(u8)] or #[repr(i8)] attribute in order to guarantee this type's alignment
--> tests/ui-msrv/enum.rs:456:10
|
456 | #[derive(Unaligned)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)
error: must have #[repr(u8)] or #[repr(i8)] attribute in order to guarantee this type's alignment
--> tests/ui-msrv/enum.rs:462:10
|
462 | #[derive(Unaligned)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)
error: must have #[repr(u8)] or #[repr(i8)] attribute in order to guarantee this type's alignment
--> tests/ui-msrv/enum.rs:468:10
|
468 | #[derive(Unaligned)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)
error: must have #[repr(u8)] or #[repr(i8)] attribute in order to guarantee this type's alignment
--> tests/ui-msrv/enum.rs:474:10
|
474 | #[derive(Unaligned)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)
error: must have #[repr(u8)] or #[repr(i8)] attribute in order to guarantee this type's alignment
--> tests/ui-msrv/enum.rs:480:10
|
480 | #[derive(Unaligned)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)
error: must have #[repr(u8)] or #[repr(i8)] attribute in order to guarantee this type's alignment
--> tests/ui-msrv/enum.rs:486:10
|
486 | #[derive(Unaligned)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)
error: must have #[repr(u8)] or #[repr(i8)] attribute in order to guarantee this type's alignment
--> tests/ui-msrv/enum.rs:492:10
|
492 | #[derive(Unaligned)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)
error: must have #[repr(u8)] or #[repr(i8)] attribute in order to guarantee this type's alignment
--> tests/ui-msrv/enum.rs:498:10
|
498 | #[derive(Unaligned)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)
error: must have #[repr(u8)] or #[repr(i8)] attribute in order to guarantee this type's alignment
--> tests/ui-msrv/enum.rs:504:10
|
504 | #[derive(Unaligned)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)
error: cannot derive `Unaligned` on type with alignment greater than 1
--> tests/ui-msrv/enum.rs:511:12
|
511 | #[repr(u8, align(2))]
| ^^^^^
error: cannot derive `Unaligned` on type with alignment greater than 1
--> tests/ui-msrv/enum.rs:517:12
|
517 | #[repr(i8, align(2))]
| ^^^^^
error: this conflicts with another representation hint
--> tests/ui-msrv/enum.rs:523:18
|
523 | #[repr(align(1), align(2))]
| ^^^^^
error: this conflicts with another representation hint
--> tests/ui-msrv/enum.rs:529:18
|
529 | #[repr(align(2), align(4))]
| ^^^^^
error: must have #[repr(C)] or #[repr(Int)] attribute in order to guarantee this type's memory layout
--> tests/ui-msrv/enum.rs:562:10
|
562 | #[derive(IntoBytes)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error: must have #[repr(C)] or #[repr(Int)] attribute in order to guarantee this type's memory layout
--> tests/ui-msrv/enum.rs:568:10
|
568 | #[derive(IntoBytes)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error: generic parameters may not be used in const operations
--> tests/ui-msrv/enum.rs:576:7
|
576 | A(T),
| ^ cannot perform const operation using `T`
|
= note: type parameters may not be used in const expressions
error[E0658]: custom discriminant values are not allowed in enums with tuple or struct variants
--> tests/ui-msrv/enum.rs:136:9
|
136 | A = 1,
| ^ disallowed custom discriminant
137 | B(NotFromZeros),
| --------------- tuple variant defined here
|
= note: see issue #60553 <https://github.com/rust-lang/rust/issues/60553> for more information
error[E0565]: meta item in `repr` must be an identifier
--> tests/ui-msrv/enum.rs:19:8
|
19 | #[repr("foo")]
| ^^^^^
error[E0552]: unrecognized representation hint
--> tests/ui-msrv/enum.rs:25:8
|
25 | #[repr(foo)]
| ^^^
error[E0566]: conflicting representation hints
--> tests/ui-msrv/enum.rs:37:8
|
37 | #[repr(u8, u16)]
| ^^ ^^^
|
= note: `#[deny(conflicting_repr_hints)]` on by default
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #68585 <https://github.com/rust-lang/rust/issues/68585>
error[E0277]: the trait bound `UnsafeCell<()>: Immutable` is not satisfied
--> tests/ui-msrv/enum.rs:51:10
|
51 | #[derive(Immutable)]
| ^^^^^^^^^ the trait `Immutable` is not implemented for `UnsafeCell<()>`
|
= help: see issue #48214
= note: this error originates in the derive macro `Immutable` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `UnsafeCell<u8>: Immutable` is not satisfied
--> tests/ui-msrv/enum.rs:59:10
|
59 | #[derive(Immutable)]
| ^^^^^^^^^ the trait `Immutable` is not implemented for `UnsafeCell<u8>`
|
= help: see issue #48214
= note: this error originates in the derive macro `Immutable` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `NotTryFromBytes: TryFromBytes` is not satisfied
--> tests/ui-msrv/enum.rs:82:10
|
82 | #[derive(TryFromBytes)]
| ^^^^^^^^^^^^ the trait `TryFromBytes` is not implemented for `NotTryFromBytes`
|
= help: see issue #48214
= note: this error originates in the derive macro `TryFromBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `NotFromZeros: TryFromBytes` is not satisfied
--> tests/ui-msrv/enum.rs:127:10
|
127 | #[derive(FromZeros)]
| ^^^^^^^^^ the trait `TryFromBytes` is not implemented for `NotFromZeros`
|
= help: see issue #48214
= note: this error originates in the derive macro `FromZeros` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `NotFromZeros: FromZeros` is not satisfied
--> tests/ui-msrv/enum.rs:127:10
|
127 | #[derive(FromZeros)]
| ^^^^^^^^^ the trait `FromZeros` is not implemented for `NotFromZeros`
|
= help: see issue #48214
= note: this error originates in the derive macro `FromZeros` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `bool: FromBytes` is not satisfied
--> tests/ui-msrv/enum.rs:191:10
|
191 | #[derive(FromBytes)]
| ^^^^^^^^^ the trait `FromBytes` is not implemented for `bool`
|
= 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 `(): PaddingFree<IntoBytes1, 1_usize>` is not satisfied
--> tests/ui-msrv/enum.rs:538:10
|
538 | #[derive(IntoBytes)]
| ^^^^^^^^^ the trait `PaddingFree<IntoBytes1, 1_usize>` is not implemented for `()`
|
= help: the following implementations were found:
<() as PaddingFree<T, 0_usize>>
= help: see issue #48214
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `(): PaddingFree<IntoBytes2, 3_usize>` is not satisfied
--> tests/ui-msrv/enum.rs:549:10
|
549 | #[derive(IntoBytes)]
| ^^^^^^^^^ the trait `PaddingFree<IntoBytes2, 3_usize>` is not implemented for `()`
|
= help: the following implementations were found:
<() as PaddingFree<T, 0_usize>>
= help: see issue #48214
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `(): PaddingFree<IntoBytes3, 2_usize>` is not satisfied
--> tests/ui-msrv/enum.rs:555:10
|
555 | #[derive(IntoBytes)]
| ^^^^^^^^^ the trait `PaddingFree<IntoBytes3, 2_usize>` is not implemented for `()`
|
= help: the following implementations were found:
<() as PaddingFree<T, 0_usize>>
= help: see issue #48214
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error: generic `Self` types are currently not permitted in anonymous constants
--> tests/ui-msrv/enum.rs:573:10
|
573 | #[derive(IntoBytes)]
| ^^^^^^^^^
|
note: not a concrete type
--> tests/ui-msrv/enum.rs:573:10
|
573 | #[derive(IntoBytes)]
| ^^^^^^^^^
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)

View File

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

View File

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

View File

@@ -0,0 +1,85 @@
// Copyright 2019 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.
#[macro_use]
extern crate zerocopy;
#[path = "../include.rs"]
mod util;
use zerocopy::KnownLayout;
use self::util::util::{NotZerocopy, AU16};
fn main() {}
// These tests cause errors which are generated by a later compilation pass than
// the other errors we generate, and so if they're compiled in the same file,
// the compiler will never get to that pass, and so we won't get the errors.
//
// TryFromBytes errors
//
#[derive(TryFromBytes)]
struct TryFromBytes1 {
value: NotZerocopy,
}
//
// FromZeros errors
//
#[derive(FromZeros)]
struct FromZeros1 {
value: NotZerocopy,
}
//
// FromBytes errors
//
#[derive(FromBytes)]
struct FromBytes1 {
value: NotZerocopy,
}
//
// IntoBytes errors
//
#[derive(IntoBytes)]
#[repr(C)]
struct IntoBytes1 {
value: NotZerocopy,
}
//
// Unaligned errors
//
#[derive(Unaligned)]
#[repr(C)]
struct Unaligned1 {
aligned: AU16,
}
// This specifically tests a bug we had in an old version of the code in which
// the trait bound would only be enforced for the first field's type.
#[derive(Unaligned)]
#[repr(C)]
struct Unaligned2 {
unaligned: u8,
aligned: AU16,
}
#[derive(Unaligned)]
#[repr(transparent)]
struct Unaligned3 {
aligned: AU16,
}

View File

@@ -0,0 +1,97 @@
warning: unused import: `zerocopy::KnownLayout`
--> tests/ui-msrv/late_compile_pass.rs:15:5
|
15 | use zerocopy::KnownLayout;
| ^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(unused_imports)]` on by default
error[E0277]: the trait bound `NotZerocopy: zerocopy::TryFromBytes` is not satisfied
--> tests/ui-msrv/late_compile_pass.rs:29:10
|
29 | #[derive(TryFromBytes)]
| ^^^^^^^^^^^^ the trait `zerocopy::TryFromBytes` is not implemented for `NotZerocopy`
|
= help: see issue #48214
= note: this error originates in the derive macro `TryFromBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `NotZerocopy: zerocopy::TryFromBytes` is not satisfied
--> tests/ui-msrv/late_compile_pass.rs:38:10
|
38 | #[derive(FromZeros)]
| ^^^^^^^^^ the trait `zerocopy::TryFromBytes` is not implemented for `NotZerocopy`
|
= help: see issue #48214
= note: this error originates in the derive macro `FromZeros` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `NotZerocopy: FromZeros` is not satisfied
--> tests/ui-msrv/late_compile_pass.rs:38:10
|
38 | #[derive(FromZeros)]
| ^^^^^^^^^ the trait `FromZeros` is not implemented for `NotZerocopy`
|
= help: see issue #48214
= note: this error originates in the derive macro `FromZeros` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `NotZerocopy: zerocopy::TryFromBytes` is not satisfied
--> tests/ui-msrv/late_compile_pass.rs:47:10
|
47 | #[derive(FromBytes)]
| ^^^^^^^^^ the trait `zerocopy::TryFromBytes` 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 `NotZerocopy: FromZeros` is not satisfied
--> tests/ui-msrv/late_compile_pass.rs:47:10
|
47 | #[derive(FromBytes)]
| ^^^^^^^^^ the trait `FromZeros` 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 `NotZerocopy: zerocopy::FromBytes` is not satisfied
--> tests/ui-msrv/late_compile_pass.rs:47:10
|
47 | #[derive(FromBytes)]
| ^^^^^^^^^ the trait `zerocopy::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 `NotZerocopy: zerocopy::IntoBytes` is not satisfied
--> tests/ui-msrv/late_compile_pass.rs:56:10
|
56 | #[derive(IntoBytes)]
| ^^^^^^^^^ the trait `zerocopy::IntoBytes` is not implemented for `NotZerocopy`
|
= help: see issue #48214
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `AU16: zerocopy::Unaligned` is not satisfied
--> tests/ui-msrv/late_compile_pass.rs:66:10
|
66 | #[derive(Unaligned)]
| ^^^^^^^^^ the trait `zerocopy::Unaligned` is not implemented for `AU16`
|
= help: see issue #48214
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `AU16: zerocopy::Unaligned` is not satisfied
--> tests/ui-msrv/late_compile_pass.rs:74:10
|
74 | #[derive(Unaligned)]
| ^^^^^^^^^ the trait `zerocopy::Unaligned` is not implemented for `AU16`
|
= help: see issue #48214
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `AU16: zerocopy::Unaligned` is not satisfied
--> tests/ui-msrv/late_compile_pass.rs:81:10
|
81 | #[derive(Unaligned)]
| ^^^^^^^^^ the trait `zerocopy::Unaligned` is not implemented for `AU16`
|
= help: see issue #48214
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)

View File

@@ -0,0 +1,61 @@
// Copyright 2023 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.
extern crate zerocopy;
use zerocopy::KnownLayout;
fn main() {}
// These tests cause errors which are generated by a later compilation pass than
// the other errors we generate, and so if they're compiled in the same file,
// the compiler will never get to that pass, and so we won't get the errors.
//
// KnownLayout errors
//
fn assert_kl<T: ?Sized + KnownLayout>(_: &T) {}
// | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
// | N | Y | N | N | KL04 |
#[derive(KnownLayout)]
struct KL04<T: ?Sized>(u8, T);
fn test_kl04<T: ?Sized>(kl: &KL04<T>) {
assert_kl(kl);
}
// | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
// | N | Y | Y | N | KL06 |
#[derive(KnownLayout)]
struct KL06<T: ?Sized + KnownLayout>(u8, T);
fn test_kl06<T: ?Sized + KnownLayout>(kl: &KL06<T>) {
assert_kl(kl);
}
// | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
// | Y | Y | N | N | KL12 |
#[derive(KnownLayout)]
#[repr(C)]
struct KL12<T: ?Sized>(u8, T);
fn test_kl12<T: ?Sized>(kl: &KL12<T>) {
assert_kl(kl)
}
// | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
// | Y | Y | N | Y | KL13 |
#[derive(KnownLayout)]
#[repr(C)]
struct KL13<T>(u8, T);
fn test_kl13<T>(t: T) -> impl KnownLayout {
KL13(0u8, t)
}

View File

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

View File

@@ -0,0 +1,38 @@
// Copyright 2024 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.
// This file contains tests which trigger errors on MSRV during a different
// compiler pass compared to the stable or nightly toolchains.
#[macro_use]
extern crate zerocopy;
#[path = "../include.rs"]
mod util;
use zerocopy::IntoBytes;
use self::util::util::AU16;
fn main() {}
// `repr(C, packed(2))` is not equivalent to `repr(C, packed)`.
#[derive(IntoBytes)]
#[repr(C, packed(2))]
struct IntoBytes1<T> {
t0: T,
// Add a second field to avoid triggering the "repr(C) struct with one
// field" special case.
t1: T,
}
fn is_into_bytes_1<T: IntoBytes>() {
if false {
is_into_bytes_1::<IntoBytes1<AU16>>();
}
}

View File

@@ -0,0 +1,25 @@
warning: unused `#[macro_use]` import
--> tests/ui-msrv/msrv_specific.rs:12:1
|
12 | #[macro_use]
| ^^^^^^^^^^^^
|
= note: `#[warn(unused_imports)]` on by default
error[E0277]: the trait bound `AU16: zerocopy::Unaligned` is not satisfied
--> tests/ui-msrv/msrv_specific.rs:36:9
|
36 | is_into_bytes_1::<IntoBytes1<AU16>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `zerocopy::Unaligned` is not implemented for `AU16`
|
note: required because of the requirements on the impl of `zerocopy::IntoBytes` for `IntoBytes1<AU16>`
--> tests/ui-msrv/msrv_specific.rs:25:10
|
25 | #[derive(IntoBytes)]
| ^^^^^^^^^
note: required by a bound in `is_into_bytes_1`
--> tests/ui-msrv/msrv_specific.rs:34:23
|
34 | fn is_into_bytes_1<T: IntoBytes>() {
| ^^^^^^^^^ required by this bound in `is_into_bytes_1`
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)

View File

@@ -0,0 +1,254 @@
// Copyright 2019 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.
#[macro_use]
extern crate zerocopy;
#[path = "../include.rs"]
mod util;
use zerocopy::{IntoBytes, KnownLayout};
use self::util::util::AU16;
fn main() {}
//
// KnownLayout errors
//
struct NotKnownLayout;
struct NotKnownLayoutDst([u8]);
// | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
// | N | N | N | N | KL00 |
#[derive(KnownLayout)]
struct KL00(u8, NotKnownLayoutDst);
// | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
// | N | N | Y | N | KL02 |
#[derive(KnownLayout)]
struct KL02(u8, [u8]);
// | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
// | Y | N | N | N | KL08 |
#[derive(KnownLayout)]
#[repr(C)]
struct KL08(u8, NotKnownLayoutDst);
// | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
// | Y | N | N | Y | KL09 |
#[derive(KnownLayout)]
#[repr(C)]
struct KL09(NotKnownLayout, NotKnownLayout);
//
// Immutable errors
//
#[derive(Immutable)]
struct Immutable1 {
a: core::cell::UnsafeCell<()>,
}
#[derive(Immutable)]
struct Immutable2 {
a: [core::cell::UnsafeCell<u8>; 0],
}
//
// TryFromBytes errors
//
#[derive(TryFromBytes)]
#[repr(packed)]
struct TryFromBytesPacked {
foo: AU16,
}
#[derive(TryFromBytes)]
#[repr(packed(1))]
struct TryFromBytesPackedN {
foo: AU16,
}
#[derive(TryFromBytes)]
#[repr(C, packed)]
struct TryFromBytesCPacked {
foo: AU16,
}
#[derive(TryFromBytes)]
#[repr(C, packed(1))]
struct TryFromBytesCPackedN {
foo: AU16,
}
//
// IntoBytes errors
//
// Since `IntoBytes1` has at least one generic parameter, an `IntoBytes` impl is
// emitted in which each field type is given an `Unaligned` bound. Since `foo`'s
// type doesn't implement `Unaligned`, this should fail.
#[derive(IntoBytes)]
#[repr(C)]
struct IntoBytes1<T> {
foo: AU16,
bar: T,
}
#[derive(IntoBytes)]
#[repr(C)]
struct IntoBytes2 {
foo: u8,
bar: AU16,
}
#[derive(IntoBytes)]
#[repr(C, packed(2))]
struct IntoBytes3 {
foo: u8,
// We'd prefer to use AU64 here, but you can't use aligned types in
// packed structs.
bar: u64,
}
type SliceU8 = [u8];
// Padding between `u8` and `SliceU8`. `SliceU8` doesn't syntactically look like
// a slice, so this case is handled by our `Sized` support.
//
// NOTE(#1708): This exists to ensure that our error messages are good when a
// field is unsized.
#[derive(IntoBytes)]
#[repr(C)]
struct IntoBytes4 {
a: u8,
b: SliceU8,
}
// Padding between `u8` and `[u16]`. `[u16]` is syntactically identifiable as a
// slice, so this case is handled by our `repr(C)` slice DST support.
#[derive(IntoBytes)]
#[repr(C)]
struct IntoBytes5 {
a: u8,
b: [u16],
}
// Trailing padding after `[u8]`. `[u8]` is syntactically identifiable as a
// slice, so this case is handled by our `repr(C)` slice DST support.
#[derive(IntoBytes)]
#[repr(C)]
struct IntoBytes6 {
a: u16,
b: [u8],
}
// Padding between `u8` and `u16` and also trailing padding after `[u8]`. `[u8]`
// is syntactically identifiable as a slice, so this case is handled by our
// `repr(C)` slice DST support.
#[derive(IntoBytes)]
#[repr(C)]
struct IntoBytes7 {
a: u8,
b: u16,
c: [u8],
}
#[derive(IntoBytes)]
#[repr(C, C)] // zerocopy-derive conservatively treats these as conflicting reprs
struct IntoBytes8 {
a: u8,
}
#[derive(IntoBytes)]
struct IntoBytes9<T> {
t: T,
}
#[derive(IntoBytes)]
#[repr(packed(2))]
struct IntoBytes10<T> {
t: T,
}
// `repr(C, packed(2))` is not equivalent to `repr(C, packed)`.
#[derive(IntoBytes)]
#[repr(C, packed(2))]
struct IntoBytes11<T> {
t0: T,
// Add a second field to avoid triggering the "repr(C) struct with one
// field" special case.
t1: T,
}
fn is_into_bytes_11<T: IntoBytes>() {
if false {
is_into_bytes_11::<IntoBytes11<AU16>>();
}
}
// `repr(C, align(2))` is not sufficient to guarantee the layout of this type.
#[derive(IntoBytes)]
#[repr(C, align(2))]
struct IntoBytes12<T> {
t: T,
}
//
// Unaligned errors
//
#[derive(Unaligned)]
#[repr(C, align(2))]
struct Unaligned1;
#[derive(Unaligned)]
#[repr(transparent, align(2))]
struct Unaligned2 {
foo: u8,
}
#[derive(Unaligned)]
#[repr(packed, align(2))]
struct Unaligned3;
#[derive(Unaligned)]
#[repr(align(1), align(2))]
struct Unaligned4;
#[derive(Unaligned)]
#[repr(align(2), align(4))]
struct Unaligned5;
#[derive(Unaligned)]
struct Unaligned6;
#[derive(Unaligned)]
#[repr(packed(2))]
struct Unaligned7;
// Test the error message emitted when conflicting reprs appear on different
// lines. On the nightly compiler, this emits a "joint span" that spans both
// problematic repr token trees and everything in between.
#[derive(Copy, Clone)]
#[repr(packed(2), C)]
#[derive(Unaligned)]
#[repr(C, packed(2))]
struct WeirdReprSpan;
#[derive(SplitAt)]
#[repr(C)]
struct SplitAtNotKnownLayout([u8]);
#[derive(SplitAt, KnownLayout)]
#[repr(C)]
struct SplitAtSized(u8);

View File

@@ -0,0 +1,281 @@
error: this conflicts with another representation hint
--> tests/ui-msrv/struct.rs:167:11
|
167 | #[repr(C, C)] // zerocopy-derive conservatively treats these as conflicting reprs
| ^
error: must have a non-align #[repr(...)] attribute in order to guarantee this type's memory layout
--> tests/ui-msrv/struct.rs:172:10
|
172 | #[derive(IntoBytes)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error: must have a non-align #[repr(...)] attribute in order to guarantee this type's memory layout
--> tests/ui-msrv/struct.rs:177:10
|
177 | #[derive(IntoBytes)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error: must have a non-align #[repr(...)] attribute in order to guarantee this type's memory layout
--> tests/ui-msrv/struct.rs:200:10
|
200 | #[derive(IntoBytes)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error: cannot derive `Unaligned` on type with alignment greater than 1
--> tests/ui-msrv/struct.rs:211:11
|
211 | #[repr(C, align(2))]
| ^^^^^
error: this conflicts with another representation hint
--> tests/ui-msrv/struct.rs:215:8
|
215 | #[repr(transparent, align(2))]
| ^^^^^^^^^^^
error: this conflicts with another representation hint
--> tests/ui-msrv/struct.rs:221:16
|
221 | #[repr(packed, align(2))]
| ^^^^^
error: this conflicts with another representation hint
--> tests/ui-msrv/struct.rs:225:18
|
225 | #[repr(align(1), align(2))]
| ^^^^^
error: this conflicts with another representation hint
--> tests/ui-msrv/struct.rs:229:18
|
229 | #[repr(align(2), align(4))]
| ^^^^^
error: must have #[repr(C)], #[repr(transparent)], or #[repr(packed)] attribute in order to guarantee this type's alignment
--> tests/ui-msrv/struct.rs:232:10
|
232 | #[derive(Unaligned)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)
error: must have #[repr(C)], #[repr(transparent)], or #[repr(packed)] attribute in order to guarantee this type's alignment
--> tests/ui-msrv/struct.rs:235:10
|
235 | #[derive(Unaligned)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)
error: this conflicts with another representation hint
--> tests/ui-msrv/struct.rs:245:8
|
245 | #[repr(C, packed(2))]
| ^
error[E0692]: transparent struct cannot have other repr hints
--> tests/ui-msrv/struct.rs:215:8
|
215 | #[repr(transparent, align(2))]
| ^^^^^^^^^^^ ^^^^^^^^
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
--> tests/ui-msrv/struct.rs:31:10
|
31 | #[derive(KnownLayout)]
| ^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: within `KL00`, the trait `Sized` is not implemented for `[u8]`
note: required because it appears within the type `KL00`
--> tests/ui-msrv/struct.rs:32:8
|
32 | struct KL00(u8, NotKnownLayoutDst);
| ^^^^
= help: see issue #48214
= note: this error originates in the derive macro `KnownLayout` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
--> tests/ui-msrv/struct.rs:36:10
|
36 | #[derive(KnownLayout)]
| ^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: within `KL02`, the trait `Sized` is not implemented for `[u8]`
note: required because it appears within the type `KL02`
--> tests/ui-msrv/struct.rs:37:8
|
37 | struct KL02(u8, [u8]);
| ^^^^
= help: see issue #48214
= note: this error originates in the derive macro `KnownLayout` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `NotKnownLayoutDst: zerocopy::KnownLayout` is not satisfied
--> tests/ui-msrv/struct.rs:41:10
|
41 | #[derive(KnownLayout)]
| ^^^^^^^^^^^ the trait `zerocopy::KnownLayout` is not implemented for `NotKnownLayoutDst`
|
= help: see issue #48214
= note: this error originates in the derive macro `KnownLayout` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `NotKnownLayout: zerocopy::KnownLayout` is not satisfied
--> tests/ui-msrv/struct.rs:47:10
|
47 | #[derive(KnownLayout)]
| ^^^^^^^^^^^ the trait `zerocopy::KnownLayout` is not implemented for `NotKnownLayout`
|
= help: see issue #48214
= note: this error originates in the derive macro `KnownLayout` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `UnsafeCell<()>: zerocopy::Immutable` is not satisfied
--> tests/ui-msrv/struct.rs:55:10
|
55 | #[derive(Immutable)]
| ^^^^^^^^^ the trait `zerocopy::Immutable` is not implemented for `UnsafeCell<()>`
|
= help: see issue #48214
= note: this error originates in the derive macro `Immutable` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `UnsafeCell<u8>: zerocopy::Immutable` is not satisfied
--> tests/ui-msrv/struct.rs:60:10
|
60 | #[derive(Immutable)]
| ^^^^^^^^^ the trait `zerocopy::Immutable` is not implemented for `UnsafeCell<u8>`
|
= note: required because of the requirements on the impl of `zerocopy::Immutable` for `[UnsafeCell<u8>; 0]`
= help: see issue #48214
= note: this error originates in the derive macro `Immutable` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `AU16: zerocopy::Unaligned` is not satisfied
--> tests/ui-msrv/struct.rs:100:10
|
100 | #[derive(IntoBytes)]
| ^^^^^^^^^ the trait `zerocopy::Unaligned` is not implemented for `AU16`
|
= help: see issue #48214
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `(): PaddingFree<IntoBytes2, 1_usize>` is not satisfied
--> tests/ui-msrv/struct.rs:107:10
|
107 | #[derive(IntoBytes)]
| ^^^^^^^^^ the trait `PaddingFree<IntoBytes2, 1_usize>` is not implemented for `()`
|
= help: the following implementations were found:
<() as PaddingFree<T, 0_usize>>
= help: see issue #48214
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `(): PaddingFree<IntoBytes3, 1_usize>` is not satisfied
--> tests/ui-msrv/struct.rs:114:10
|
114 | #[derive(IntoBytes)]
| ^^^^^^^^^ the trait `PaddingFree<IntoBytes3, 1_usize>` is not implemented for `()`
|
= help: the following implementations were found:
<() as PaddingFree<T, 0_usize>>
= help: see issue #48214
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
--> tests/ui-msrv/struct.rs:130:10
|
130 | #[derive(IntoBytes)]
| ^^^^^^^^^ doesn't have a size known at compile-time
|
= help: within `IntoBytes4`, the trait `Sized` is not implemented for `[u8]`
note: required because it appears within the type `IntoBytes4`
--> tests/ui-msrv/struct.rs:132:8
|
132 | struct IntoBytes4 {
| ^^^^^^^^^^
note: required by a bound in `std::mem::size_of`
--> $RUST/core/src/mem/mod.rs
|
| pub const fn size_of<T>() -> usize {
| ^ required by this bound in `std::mem::size_of`
= note: this error originates in the macro `::zerocopy::struct_padding` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
--> tests/ui-msrv/struct.rs:134:8
|
134 | b: SliceU8,
| ^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `[u8]`
note: required by a bound in `std::mem::size_of`
--> $RUST/core/src/mem/mod.rs
|
| pub const fn size_of<T>() -> usize {
| ^ required by this bound in `std::mem::size_of`
error[E0277]: the trait bound `(): DynamicPaddingFree<IntoBytes5, true>` is not satisfied
--> tests/ui-msrv/struct.rs:139:10
|
139 | #[derive(IntoBytes)]
| ^^^^^^^^^ the trait `DynamicPaddingFree<IntoBytes5, true>` is not implemented for `()`
|
= help: the following implementations were found:
<() as DynamicPaddingFree<T, false>>
= help: see issue #48214
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `(): DynamicPaddingFree<IntoBytes6, true>` is not satisfied
--> tests/ui-msrv/struct.rs:148:10
|
148 | #[derive(IntoBytes)]
| ^^^^^^^^^ the trait `DynamicPaddingFree<IntoBytes6, true>` is not implemented for `()`
|
= help: the following implementations were found:
<() as DynamicPaddingFree<T, false>>
= help: see issue #48214
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `(): DynamicPaddingFree<IntoBytes7, true>` is not satisfied
--> tests/ui-msrv/struct.rs:158:10
|
158 | #[derive(IntoBytes)]
| ^^^^^^^^^ the trait `DynamicPaddingFree<IntoBytes7, true>` is not implemented for `()`
|
= help: the following implementations were found:
<() as DynamicPaddingFree<T, false>>
= help: see issue #48214
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `SplitAtNotKnownLayout: zerocopy::KnownLayout` is not satisfied
--> tests/ui-msrv/struct.rs:248:10
|
248 | #[derive(SplitAt)]
| ^^^^^^^ the trait `zerocopy::KnownLayout` is not implemented for `SplitAtNotKnownLayout`
|
note: required by a bound in `SplitAt`
--> $WORKSPACE/src/split_at.rs
|
| pub unsafe trait SplitAt: KnownLayout<PointerMetadata = usize> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `SplitAt`
= note: this error originates in the derive macro `SplitAt` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `u8: SplitAt` is not satisfied
--> tests/ui-msrv/struct.rs:252:10
|
252 | #[derive(SplitAt, KnownLayout)]
| ^^^^^^^ the trait `SplitAt` is not implemented for `u8`
|
= help: see issue #48214
= note: this error originates in the derive macro `SplitAt` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0271]: type mismatch resolving `<u8 as zerocopy::KnownLayout>::PointerMetadata == usize`
--> tests/ui-msrv/struct.rs:252:10
|
252 | #[derive(SplitAt, KnownLayout)]
| ^^^^^^^ expected `()`, found `usize`
|
= help: see issue #48214
= note: this error originates in the derive macro `SplitAt` (in Nightly builds, run with -Z macro-backtrace for more info)

View File

@@ -0,0 +1,109 @@
// Copyright 2019 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.
#[macro_use]
extern crate zerocopy;
#[path = "../include.rs"]
mod util;
use std::mem::ManuallyDrop;
use self::util::util::AU16;
fn main() {}
//
// Immutable errors
//
#[derive(Immutable)]
union Immutable1 {
a: ManuallyDrop<core::cell::UnsafeCell<()>>,
}
//
// IntoBytes errors
//
#[derive(IntoBytes)]
#[repr(C)]
union IntoBytes1<T> {
foo: ManuallyDrop<T>,
}
#[derive(IntoBytes)]
#[repr(C)]
union IntoBytes2 {
foo: u8,
bar: [u8; 2],
}
// Need a `repr` attribute
#[derive(IntoBytes)]
union IntoBytes3 {
foo: u8,
}
// `repr(packed(2))` isn't equivalent to `repr(packed)`
#[derive(IntoBytes)]
#[repr(packed(2))]
union IntoBytes4 {
foo: u8,
}
//
// Unaligned errors
//
#[derive(Unaligned)]
#[repr(C, align(2))]
union Unaligned1 {
foo: i16,
bar: AU16,
}
// Transparent unions are unstable; see issue #60405
// <https://github.com/rust-lang/rust/issues/60405> for more information.
// #[derive(Unaligned)]
// #[repr(transparent, align(2))]
// union Unaligned2 {
// foo: u8,
// }
#[derive(Unaligned)]
#[repr(packed, align(2))]
union Unaligned3 {
foo: u8,
}
#[derive(Unaligned)]
#[repr(align(1), align(2))]
struct Unaligned4 {
foo: u8,
}
#[derive(Unaligned)]
#[repr(align(2), align(4))]
struct Unaligned5 {
foo: u8,
}
#[derive(Unaligned)]
union Unaligned6 {
foo: i16,
bar: AU16,
}
#[derive(Unaligned)]
#[repr(packed(2))]
union Unaligned7 {
foo: i16,
bar: AU16,
}

View File

@@ -0,0 +1,84 @@
error: unsupported on types with type parameters
--> tests/ui-msrv/union.rs:34:10
|
34 | #[derive(IntoBytes)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error: must be #[repr(C)], #[repr(packed)], or #[repr(transparent)]
--> tests/ui-msrv/union.rs:48:10
|
48 | #[derive(IntoBytes)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error: must be #[repr(C)], #[repr(packed)], or #[repr(transparent)]
--> tests/ui-msrv/union.rs:54:10
|
54 | #[derive(IntoBytes)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error: cannot derive `Unaligned` on type with alignment greater than 1
--> tests/ui-msrv/union.rs:65:11
|
65 | #[repr(C, align(2))]
| ^^^^^
error: this conflicts with another representation hint
--> tests/ui-msrv/union.rs:81:16
|
81 | #[repr(packed, align(2))]
| ^^^^^
error: this conflicts with another representation hint
--> tests/ui-msrv/union.rs:87:18
|
87 | #[repr(align(1), align(2))]
| ^^^^^
error: this conflicts with another representation hint
--> tests/ui-msrv/union.rs:93:18
|
93 | #[repr(align(2), align(4))]
| ^^^^^
error: must have #[repr(C)], #[repr(transparent)], or #[repr(packed)] attribute in order to guarantee this type's alignment
--> tests/ui-msrv/union.rs:98:10
|
98 | #[derive(Unaligned)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)
error: must have #[repr(C)], #[repr(transparent)], or #[repr(packed)] attribute in order to guarantee this type's alignment
--> tests/ui-msrv/union.rs:104:10
|
104 | #[derive(Unaligned)]
| ^^^^^^^^^
|
= 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 `UnsafeCell<()>: zerocopy::Immutable` is not satisfied
--> tests/ui-msrv/union.rs:25:10
|
25 | #[derive(Immutable)]
| ^^^^^^^^^ the trait `zerocopy::Immutable` is not implemented for `UnsafeCell<()>`
|
= note: required because of the requirements on the impl of `zerocopy::Immutable` for `ManuallyDrop<UnsafeCell<()>>`
= help: see issue #48214
= note: this error originates in the derive macro `Immutable` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `(): PaddingFree<IntoBytes2, 1_usize>` is not satisfied
--> tests/ui-msrv/union.rs:40:10
|
40 | #[derive(IntoBytes)]
| ^^^^^^^^^ the trait `PaddingFree<IntoBytes2, 1_usize>` is not implemented for `()`
|
= help: the following implementations were found:
<() as PaddingFree<T, 0_usize>>
= help: see issue #48214
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)

View File

@@ -0,0 +1,26 @@
// Copyright 2024 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.
//! See: https://github.com/google/zerocopy/issues/553
//! zerocopy must still allow derives of deprecated types.
//! This test has a hand-written impl of a deprecated type, and should result in a compilation
//! error. If zerocopy does not tack an allow(deprecated) annotation onto its impls, then this
//! test will fail because more than one compile error will be generated.
#![deny(deprecated)]
extern crate zerocopy;
use zerocopy::IntoBytes;
#[derive(IntoBytes)]
#[repr(C)]
union Foo {
a: u8,
}
fn main() {}

View File

@@ -0,0 +1,8 @@
error: requires --cfg zerocopy_derive_union_into_bytes;
please let us know you use this feature: https://github.com/google/zerocopy/discussions/1802
--> tests/ui-msrv/union_into_bytes_cfg/union_into_bytes_cfg.rs:20:10
|
20 | #[derive(IntoBytes)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)

View File

@@ -0,0 +1,33 @@
// Copyright 2024 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.
//! See: https://github.com/google/zerocopy/issues/553
//! zerocopy must still allow derives of deprecated types.
//! This test has a hand-written impl of a deprecated type, and should result in a compilation
//! error. If zerocopy does not tack an allow(deprecated) annotation onto its impls, then this
//! test will fail because more than one compile error will be generated.
#![deny(deprecated)]
extern crate zerocopy;
use zerocopy::IntoBytes;
#[deprecated = "Do not use"]
#[derive(IntoBytes)]
#[repr(C)]
struct OldHeader {
field_a: usize,
collection: [u8; 8],
}
trait T {}
// Intentionally trigger a deprecation error
impl T for OldHeader {}
fn main() {}

View File

@@ -0,0 +1,11 @@
error: use of deprecated struct `OldHeader`: Do not use
--> tests/ui-nightly/absence_of_deprecated_warning.rs:31:12
|
31 | impl T for OldHeader {}
| ^^^^^^^^^
|
note: the lint level is defined here
--> tests/ui-nightly/absence_of_deprecated_warning.rs:14:9
|
14 | #![deny(deprecated)]
| ^^^^^^^^^^

View File

@@ -0,0 +1,38 @@
// Copyright 2019 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.
extern crate zerocopy;
#[path = "../include.rs"]
mod util;
use core::marker::PhantomData;
use zerocopy::{FromBytes, FromZeros, IntoBytes, TryFromBytes, Unaligned};
use self::util::util::NotZerocopy;
fn main() {}
// Test generic transparent structs
#[derive(IntoBytes, 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.
util_assert_impl_all!(TransparentStruct<NotZerocopy>: TryFromBytes);
util_assert_impl_all!(TransparentStruct<NotZerocopy>: FromZeros);
util_assert_impl_all!(TransparentStruct<NotZerocopy>: FromBytes);
util_assert_impl_all!(TransparentStruct<NotZerocopy>: IntoBytes);
util_assert_impl_all!(TransparentStruct<NotZerocopy>: Unaligned);

View File

@@ -0,0 +1,169 @@
error[E0277]: the trait bound `NotZerocopy: zerocopy::TryFromBytes` is not satisfied
--> tests/ui-nightly/derive_transparent.rs:34:23
|
34 | util_assert_impl_all!(TransparentStruct<NotZerocopy>: TryFromBytes);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unsatisfied trait bound
|
help: the trait `zerocopy::TryFromBytes` is not implemented for `NotZerocopy`
--> tests/ui-nightly/../include.rs
|
| pub struct NotZerocopy<T = ()>(pub T);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: Consider adding `#[derive(TryFromBytes)]` to `NotZerocopy`
= help: the following other types implement trait `zerocopy::TryFromBytes`:
()
*const T
*mut T
AU16
AtomicBool
AtomicI16
AtomicI32
AtomicI64
and $N others
note: required for `TransparentStruct<NotZerocopy>` to implement `zerocopy::TryFromBytes`
--> tests/ui-nightly/derive_transparent.rs:24:21
|
24 | #[derive(IntoBytes, FromBytes, Unaligned)]
| ^^^^^^^^^ unsatisfied trait bound introduced in this `derive` macro
note: required by a bound in `_::{closure#0}::_::{closure#0}::assert_impl_all`
--> tests/ui-nightly/derive_transparent.rs:34:1
|
34 | util_assert_impl_all!(TransparentStruct<NotZerocopy>: TryFromBytes);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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 `util_assert_impl_all` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `NotZerocopy: FromZeros` is not satisfied
--> tests/ui-nightly/derive_transparent.rs:35:23
|
35 | util_assert_impl_all!(TransparentStruct<NotZerocopy>: FromZeros);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unsatisfied trait bound
|
help: the trait `FromZeros` is not implemented for `NotZerocopy`
--> tests/ui-nightly/../include.rs
|
| pub struct NotZerocopy<T = ()>(pub T);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: Consider adding `#[derive(FromZeros)]` to `NotZerocopy`
= help: the following other types implement trait `FromZeros`:
()
*const T
*mut T
AU16
AtomicBool
AtomicI16
AtomicI32
AtomicI64
and $N others
note: required for `TransparentStruct<NotZerocopy>` to implement `FromZeros`
--> tests/ui-nightly/derive_transparent.rs:24:21
|
24 | #[derive(IntoBytes, FromBytes, Unaligned)]
| ^^^^^^^^^ unsatisfied trait bound introduced in this `derive` macro
note: required by a bound in `_::{closure#0}::_::{closure#0}::assert_impl_all`
--> tests/ui-nightly/derive_transparent.rs:35:1
|
35 | util_assert_impl_all!(TransparentStruct<NotZerocopy>: FromZeros);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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 `util_assert_impl_all` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `NotZerocopy: zerocopy::FromBytes` is not satisfied
--> tests/ui-nightly/derive_transparent.rs:36:23
|
36 | util_assert_impl_all!(TransparentStruct<NotZerocopy>: FromBytes);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unsatisfied trait bound
|
help: the trait `zerocopy::FromBytes` is not implemented for `NotZerocopy`
--> tests/ui-nightly/../include.rs
|
| pub struct NotZerocopy<T = ()>(pub T);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: Consider adding `#[derive(FromBytes)]` to `NotZerocopy`
= help: the following other types implement trait `zerocopy::FromBytes`:
()
AU16
AtomicI16
AtomicI32
AtomicI64
AtomicI8
AtomicIsize
AtomicU16
and $N others
note: required for `TransparentStruct<NotZerocopy>` to implement `zerocopy::FromBytes`
--> tests/ui-nightly/derive_transparent.rs:24:21
|
24 | #[derive(IntoBytes, FromBytes, Unaligned)]
| ^^^^^^^^^ unsatisfied trait bound introduced in this `derive` macro
note: required by a bound in `_::{closure#0}::_::{closure#0}::assert_impl_all`
--> tests/ui-nightly/derive_transparent.rs:36:1
|
36 | util_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 `util_assert_impl_all` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `NotZerocopy: zerocopy::IntoBytes` is not satisfied
--> tests/ui-nightly/derive_transparent.rs:37:23
|
37 | util_assert_impl_all!(TransparentStruct<NotZerocopy>: IntoBytes);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unsatisfied trait bound
|
help: the trait `zerocopy::IntoBytes` is not implemented for `NotZerocopy`
--> tests/ui-nightly/../include.rs
|
| pub struct NotZerocopy<T = ()>(pub T);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: Consider adding `#[derive(IntoBytes)]` to `NotZerocopy`
= help: the following other types implement trait `zerocopy::IntoBytes`:
()
AU16
AtomicBool
AtomicI16
AtomicI32
AtomicI64
AtomicI8
AtomicIsize
and $N others
note: required for `TransparentStruct<NotZerocopy>` to implement `zerocopy::IntoBytes`
--> tests/ui-nightly/derive_transparent.rs:24:10
|
24 | #[derive(IntoBytes, FromBytes, Unaligned)]
| ^^^^^^^^^ unsatisfied trait bound introduced in this `derive` macro
note: required by a bound in `_::{closure#0}::_::{closure#0}::assert_impl_all`
--> tests/ui-nightly/derive_transparent.rs:37:1
|
37 | util_assert_impl_all!(TransparentStruct<NotZerocopy>: IntoBytes);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `assert_impl_all`
= note: this error originates in the derive macro `IntoBytes` which comes from the expansion of the macro `util_assert_impl_all` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `NotZerocopy: zerocopy::Unaligned` is not satisfied
--> tests/ui-nightly/derive_transparent.rs:38:23
|
38 | util_assert_impl_all!(TransparentStruct<NotZerocopy>: Unaligned);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unsatisfied trait bound
|
help: the trait `zerocopy::Unaligned` is not implemented for `NotZerocopy`
--> tests/ui-nightly/../include.rs
|
| pub struct NotZerocopy<T = ()>(pub T);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: Consider adding `#[derive(Unaligned)]` to `NotZerocopy`
= help: the following other types implement trait `zerocopy::Unaligned`:
()
AtomicBool
AtomicI8
AtomicU8
Cell<T>
F32<O>
F64<O>
I128<O>
and $N others
note: required for `TransparentStruct<NotZerocopy>` to implement `zerocopy::Unaligned`
--> tests/ui-nightly/derive_transparent.rs:24:32
|
24 | #[derive(IntoBytes, FromBytes, Unaligned)]
| ^^^^^^^^^ unsatisfied trait bound introduced in this `derive` macro
note: required by a bound in `_::{closure#0}::_::{closure#0}::assert_impl_all`
--> tests/ui-nightly/derive_transparent.rs:38:1
|
38 | util_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 `util_assert_impl_all` (in Nightly builds, run with -Z macro-backtrace for more info)

View File

@@ -0,0 +1,577 @@
// Copyright 2019 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.
#[macro_use]
extern crate zerocopy;
fn main() {}
//
// Generic errors
//
#[derive(FromBytes)]
#[repr("foo")]
enum Generic1 {
A,
}
#[derive(FromBytes)]
#[repr(foo)]
enum Generic2 {
A,
}
#[derive(FromBytes)]
#[repr(transparent)]
enum Generic3 {
A,
}
#[derive(FromBytes)]
#[repr(u8, u16)]
enum Generic4 {
A,
}
#[derive(FromBytes)]
enum Generic5 {
A,
}
//
// Immutable errors
//
#[derive(Immutable)]
enum Immutable1 {
A(core::cell::UnsafeCell<()>),
}
#[derive(Immutable)]
enum Never {}
#[derive(Immutable)]
enum Immutable2 {
Uninhabited(Never, core::cell::UnsafeCell<u8>),
Inhabited(u8),
}
//
// TryFromBytes errors
//
#[derive(TryFromBytes)]
enum TryFromBytes1 {
A,
}
#[derive(TryFromBytes)]
enum TryFromBytes2 {
A,
B(u8),
}
struct NotTryFromBytes;
#[derive(TryFromBytes)]
#[repr(u8)]
enum TryFromBytes3 {
A(NotTryFromBytes),
}
//
// FromZeros errors
//
#[derive(FromZeros)]
enum FromZeros1 {
A(u8),
}
#[derive(FromZeros)]
enum FromZeros2 {
A,
B(u8),
}
#[derive(FromZeros)]
enum FromZeros3 {
A = 1,
B,
}
#[derive(FromZeros)]
#[repr(u8)]
enum FromZeros4 {
A = 1,
B = 2,
}
const NEGATIVE_ONE: i8 = -1;
#[derive(FromZeros)]
#[repr(i8)]
enum FromZeros5 {
A = NEGATIVE_ONE,
B,
}
struct NotFromZeros;
#[derive(FromZeros)]
#[repr(u8)]
enum FromZeros6 {
A(NotFromZeros),
}
#[derive(FromZeros)]
#[repr(u8)]
enum FromZeros7 {
A = 1,
B(NotFromZeros),
}
//
// FromBytes errors
//
#[derive(FromBytes)]
enum FromBytes1 {
A,
}
#[derive(FromBytes)]
#[repr(C)]
enum FromBytes2 {
A,
}
#[derive(FromBytes)]
#[repr(usize)]
enum FromBytes3 {
A,
}
#[derive(FromBytes)]
#[repr(isize)]
enum FromBytes4 {
A,
}
#[derive(FromBytes)]
#[repr(u32)]
enum FromBytes5 {
A,
}
#[derive(FromBytes)]
#[repr(i32)]
enum FromBytes6 {
A,
}
#[derive(FromBytes)]
#[repr(u64)]
enum FromBytes7 {
A,
}
#[derive(FromBytes)]
#[repr(i64)]
enum FromBytes8 {
A,
}
#[derive(FromBytes)]
#[repr(u8)]
enum FooU8 {
Variant0,
Variant1,
Variant2,
Variant3,
Variant4,
Variant5,
Variant6,
Variant7,
Variant8,
Variant9,
Variant10,
Variant11,
Variant12,
Variant13,
Variant14,
Variant15,
Variant16,
Variant17,
Variant18,
Variant19,
Variant20,
Variant21,
Variant22,
Variant23,
Variant24,
Variant25,
Variant26,
Variant27,
Variant28,
Variant29,
Variant30,
Variant31,
Variant32,
Variant33,
Variant34,
Variant35,
Variant36,
Variant37,
Variant38,
Variant39,
Variant40,
Variant41,
Variant42,
Variant43,
Variant44,
Variant45,
Variant46,
Variant47,
Variant48,
Variant49,
Variant50,
Variant51,
Variant52,
Variant53,
Variant54,
Variant55,
Variant56,
Variant57,
Variant58,
Variant59,
Variant60,
Variant61,
Variant62,
Variant63,
Variant64,
Variant65,
Variant66,
Variant67,
Variant68,
Variant69,
Variant70,
Variant71,
Variant72,
Variant73,
Variant74,
Variant75,
Variant76,
Variant77,
Variant78,
Variant79,
Variant80,
Variant81,
Variant82,
Variant83,
Variant84,
Variant85,
Variant86,
Variant87,
Variant88,
Variant89,
Variant90,
Variant91,
Variant92,
Variant93,
Variant94,
Variant95,
Variant96,
Variant97,
Variant98,
Variant99,
Variant100,
Variant101,
Variant102,
Variant103,
Variant104,
Variant105,
Variant106,
Variant107,
Variant108,
Variant109,
Variant110,
Variant111,
Variant112,
Variant113,
Variant114,
Variant115,
Variant116,
Variant117,
Variant118,
Variant119,
Variant120,
Variant121,
Variant122,
Variant123,
Variant124,
Variant125,
Variant126,
Variant127,
Variant128,
Variant129,
Variant130,
Variant131,
Variant132,
Variant133,
Variant134,
Variant135,
Variant136,
Variant137,
Variant138,
Variant139,
Variant140,
Variant141,
Variant142,
Variant143,
Variant144,
Variant145,
Variant146,
Variant147,
Variant148,
Variant149,
Variant150,
Variant151,
Variant152,
Variant153,
Variant154,
Variant155,
Variant156,
Variant157,
Variant158,
Variant159,
Variant160,
Variant161,
Variant162,
Variant163,
Variant164,
Variant165,
Variant166,
Variant167,
Variant168,
Variant169,
Variant170,
Variant171,
Variant172,
Variant173,
Variant174,
Variant175,
Variant176,
Variant177,
Variant178,
Variant179,
Variant180,
Variant181,
Variant182,
Variant183,
Variant184,
Variant185,
Variant186,
Variant187,
Variant188,
Variant189,
Variant190,
Variant191,
Variant192,
Variant193,
Variant194,
Variant195,
Variant196,
Variant197,
Variant198,
Variant199,
Variant200,
Variant201,
Variant202,
Variant203,
Variant204,
Variant205,
Variant206,
Variant207,
Variant208,
Variant209,
Variant210,
Variant211,
Variant212,
Variant213,
Variant214,
Variant215,
Variant216,
Variant217,
Variant218,
Variant219,
Variant220,
Variant221,
Variant222,
Variant223,
Variant224,
Variant225,
Variant226,
Variant227,
Variant228,
Variant229,
Variant230,
Variant231,
Variant232,
Variant233,
Variant234,
Variant235,
Variant236,
Variant237,
Variant238,
Variant239,
Variant240,
Variant241,
Variant242,
Variant243,
Variant244,
Variant245,
Variant246,
Variant247,
Variant248,
Variant249,
Variant250,
Variant251,
Variant252,
Variant253,
Variant254,
Variant255(bool),
}
//
// Unaligned errors
//
#[derive(Unaligned)]
#[repr(C)]
enum Unaligned1 {
A,
}
#[derive(Unaligned)]
#[repr(u16)]
enum Unaligned2 {
A,
}
#[derive(Unaligned)]
#[repr(i16)]
enum Unaligned3 {
A,
}
#[derive(Unaligned)]
#[repr(u32)]
enum Unaligned4 {
A,
}
#[derive(Unaligned)]
#[repr(i32)]
enum Unaligned5 {
A,
}
#[derive(Unaligned)]
#[repr(u64)]
enum Unaligned6 {
A,
}
#[derive(Unaligned)]
#[repr(i64)]
enum Unaligned7 {
A,
}
#[derive(Unaligned)]
#[repr(usize)]
enum Unaligned8 {
A,
}
#[derive(Unaligned)]
#[repr(isize)]
enum Unaligned9 {
A,
}
#[derive(Unaligned)]
#[repr(u8, align(2))]
enum Unaligned10 {
A,
}
#[derive(Unaligned)]
#[repr(i8, align(2))]
enum Unaligned11 {
A,
}
#[derive(Unaligned)]
#[repr(align(1), align(2))]
enum Unaligned12 {
A,
}
#[derive(Unaligned)]
#[repr(align(2), align(4))]
enum Unaligned13 {
A,
}
//
// IntoBytes errors
//
#[derive(IntoBytes)]
#[repr(u8)]
enum IntoBytes1 {
A,
B(u8),
}
#[derive(IntoBytes)]
#[repr(C, align(4))]
struct Align4IntoBytes(u32);
#[derive(IntoBytes)]
#[repr(u8)]
enum IntoBytes2 {
A(Align4IntoBytes),
}
#[derive(IntoBytes)]
#[repr(u32)]
enum IntoBytes3 {
A(u32),
B(u16),
}
#[derive(IntoBytes)]
enum IntoBytes4 {
A(u32),
B(u16),
}
#[derive(IntoBytes)]
enum IntoBytes5 {
A(u32),
}
#[derive(IntoBytes)]
#[repr(u8)]
enum IntoBytes6<T> {
A(T),
}

View File

@@ -0,0 +1,555 @@
error: unrecognized representation hint
--> tests/ui-nightly/enum.rs:19:8
|
19 | #[repr("foo")]
| ^^^^^
error: unrecognized representation hint
--> tests/ui-nightly/enum.rs:25:8
|
25 | #[repr(foo)]
| ^^^
error: must have #[repr(C)] or #[repr(Int)] attribute in order to guarantee this type's memory layout
--> tests/ui-nightly/enum.rs:30:10
|
30 | #[derive(FromBytes)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `FromBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error: this conflicts with another representation hint
--> tests/ui-nightly/enum.rs:37:8
|
37 | #[repr(u8, u16)]
| ^^^^^^^
error: must have #[repr(C)] or #[repr(Int)] attribute in order to guarantee this type's memory layout
--> tests/ui-nightly/enum.rs:42:10
|
42 | #[derive(FromBytes)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `FromBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error: must have #[repr(C)] or #[repr(Int)] attribute in order to guarantee this type's memory layout
--> tests/ui-nightly/enum.rs:69:10
|
69 | #[derive(TryFromBytes)]
| ^^^^^^^^^^^^
|
= note: this error originates in the derive macro `TryFromBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error: must have #[repr(C)] or #[repr(Int)] attribute in order to guarantee this type's memory layout
--> tests/ui-nightly/enum.rs:74:10
|
74 | #[derive(TryFromBytes)]
| ^^^^^^^^^^^^
|
= note: this error originates in the derive macro `TryFromBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error: must have #[repr(C)] or #[repr(Int)] attribute in order to guarantee this type's memory layout
--> tests/ui-nightly/enum.rs:92:10
|
92 | #[derive(FromZeros)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `FromZeros` (in Nightly builds, run with -Z macro-backtrace for more info)
error: must have #[repr(C)] or #[repr(Int)] attribute in order to guarantee this type's memory layout
--> tests/ui-nightly/enum.rs:97:10
|
97 | #[derive(FromZeros)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `FromZeros` (in Nightly builds, run with -Z macro-backtrace for more info)
error: must have #[repr(C)] or #[repr(Int)] attribute in order to guarantee this type's memory layout
--> tests/ui-nightly/enum.rs:103:10
|
103 | #[derive(FromZeros)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `FromZeros` (in Nightly builds, run with -Z macro-backtrace for more info)
error: FromZeros only supported on enums with a variant that has a discriminant of `0`
--> tests/ui-nightly/enum.rs:110:1
|
110 | / #[repr(u8)]
111 | | enum FromZeros4 {
112 | | A = 1,
113 | | B = 2,
114 | | }
| |_^
error: FromZeros only supported on enums with a variant that has a discriminant of `0`
help: This enum has discriminants which are not literal integers. One of those may define or imply which variant has a discriminant of zero. Use a literal integer to define or imply the variant with a discriminant of zero.
--> tests/ui-nightly/enum.rs:119:1
|
119 | / #[repr(i8)]
120 | | enum FromZeros5 {
121 | | A = NEGATIVE_ONE,
122 | | B,
123 | | }
| |_^
error: FromZeros only supported on enums with a variant that has a discriminant of `0`
--> tests/ui-nightly/enum.rs:134:1
|
134 | / #[repr(u8)]
135 | | enum FromZeros7 {
136 | | A = 1,
137 | | B(NotFromZeros),
138 | | }
| |_^
error: must have #[repr(C)] or #[repr(Int)] attribute in order to guarantee this type's memory layout
--> tests/ui-nightly/enum.rs:144:10
|
144 | #[derive(FromBytes)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `FromBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error: `FromBytes` only supported on enums with `#[repr(...)]` attributes `u8`, `i8`, `u16`, or `i16`
--> tests/ui-nightly/enum.rs:150:8
|
150 | #[repr(C)]
| ^
error: `FromBytes` only supported on enums with `#[repr(...)]` attributes `u8`, `i8`, `u16`, or `i16`
--> tests/ui-nightly/enum.rs:156:8
|
156 | #[repr(usize)]
| ^^^^^
error: `FromBytes` only supported on enums with `#[repr(...)]` attributes `u8`, `i8`, `u16`, or `i16`
--> tests/ui-nightly/enum.rs:162:8
|
162 | #[repr(isize)]
| ^^^^^
error: `FromBytes` only supported on enums with `#[repr(...)]` attributes `u8`, `i8`, `u16`, or `i16`
--> tests/ui-nightly/enum.rs:168:8
|
168 | #[repr(u32)]
| ^^^
error: `FromBytes` only supported on enums with `#[repr(...)]` attributes `u8`, `i8`, `u16`, or `i16`
--> tests/ui-nightly/enum.rs:174:8
|
174 | #[repr(i32)]
| ^^^
error: `FromBytes` only supported on enums with `#[repr(...)]` attributes `u8`, `i8`, `u16`, or `i16`
--> tests/ui-nightly/enum.rs:180:8
|
180 | #[repr(u64)]
| ^^^
error: `FromBytes` only supported on enums with `#[repr(...)]` attributes `u8`, `i8`, `u16`, or `i16`
--> tests/ui-nightly/enum.rs:186:8
|
186 | #[repr(i64)]
| ^^^
error: must have #[repr(u8)] or #[repr(i8)] attribute in order to guarantee this type's alignment
--> tests/ui-nightly/enum.rs:456:10
|
456 | #[derive(Unaligned)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)
error: must have #[repr(u8)] or #[repr(i8)] attribute in order to guarantee this type's alignment
--> tests/ui-nightly/enum.rs:462:10
|
462 | #[derive(Unaligned)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)
error: must have #[repr(u8)] or #[repr(i8)] attribute in order to guarantee this type's alignment
--> tests/ui-nightly/enum.rs:468:10
|
468 | #[derive(Unaligned)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)
error: must have #[repr(u8)] or #[repr(i8)] attribute in order to guarantee this type's alignment
--> tests/ui-nightly/enum.rs:474:10
|
474 | #[derive(Unaligned)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)
error: must have #[repr(u8)] or #[repr(i8)] attribute in order to guarantee this type's alignment
--> tests/ui-nightly/enum.rs:480:10
|
480 | #[derive(Unaligned)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)
error: must have #[repr(u8)] or #[repr(i8)] attribute in order to guarantee this type's alignment
--> tests/ui-nightly/enum.rs:486:10
|
486 | #[derive(Unaligned)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)
error: must have #[repr(u8)] or #[repr(i8)] attribute in order to guarantee this type's alignment
--> tests/ui-nightly/enum.rs:492:10
|
492 | #[derive(Unaligned)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)
error: must have #[repr(u8)] or #[repr(i8)] attribute in order to guarantee this type's alignment
--> tests/ui-nightly/enum.rs:498:10
|
498 | #[derive(Unaligned)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)
error: must have #[repr(u8)] or #[repr(i8)] attribute in order to guarantee this type's alignment
--> tests/ui-nightly/enum.rs:504:10
|
504 | #[derive(Unaligned)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)
error: cannot derive `Unaligned` on type with alignment greater than 1
--> tests/ui-nightly/enum.rs:511:12
|
511 | #[repr(u8, align(2))]
| ^^^^^^^^
error: cannot derive `Unaligned` on type with alignment greater than 1
--> tests/ui-nightly/enum.rs:517:12
|
517 | #[repr(i8, align(2))]
| ^^^^^^^^
error: this conflicts with another representation hint
--> tests/ui-nightly/enum.rs:523:8
|
523 | #[repr(align(1), align(2))]
| ^^^^^^^^^^^^^^^^^^
error: this conflicts with another representation hint
--> tests/ui-nightly/enum.rs:529:8
|
529 | #[repr(align(2), align(4))]
| ^^^^^^^^^^^^^^^^^^
error: must have #[repr(C)] or #[repr(Int)] attribute in order to guarantee this type's memory layout
--> tests/ui-nightly/enum.rs:562:10
|
562 | #[derive(IntoBytes)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error: must have #[repr(C)] or #[repr(Int)] attribute in order to guarantee this type's memory layout
--> tests/ui-nightly/enum.rs:568:10
|
568 | #[derive(IntoBytes)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error: generic parameters may not be used in const operations
--> tests/ui-nightly/enum.rs:576:7
|
576 | A(T),
| ^ cannot perform const operation using `T`
|
= note: type parameters may not be used in const expressions
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
error[E0565]: meta item in `repr` must be an identifier
--> tests/ui-nightly/enum.rs:19:1
|
19 | #[repr("foo")]
| ^^^^^^^^^^^^^^
error[E0552]: unrecognized representation hint
--> tests/ui-nightly/enum.rs:25:8
|
25 | #[repr(foo)]
| ^^^
|
= help: valid reprs are `Rust` (default), `C`, `align`, `packed`, `transparent`, `simd`, `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize`
= note: for more information, visit <https://doc.rust-lang.org/reference/type-layout.html?highlight=repr#representations>
error[E0566]: conflicting representation hints
--> tests/ui-nightly/enum.rs:37:8
|
37 | #[repr(u8, u16)]
| ^^ ^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #68585 <https://github.com/rust-lang/rust/issues/68585>
= note: `#[deny(conflicting_repr_hints)]` (part of `#[deny(future_incompatible)]`) on by default
error[E0277]: the trait bound `UnsafeCell<()>: Immutable` is not satisfied
--> tests/ui-nightly/enum.rs:51:10
|
51 | #[derive(Immutable)]
| ^^^^^^^^^ the trait `Immutable` is not implemented for `UnsafeCell<()>`
|
= note: Consider adding `#[derive(Immutable)]` to `UnsafeCell<()>`
= help: the following other types implement trait `Immutable`:
&T
&mut T
()
*const T
*mut T
F32<O>
F64<O>
I128<O>
and $N others
= help: see issue #48214
= note: this error originates in the derive macro `Immutable` (in Nightly builds, run with -Z macro-backtrace for more info)
help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
|
9 + #![feature(trivial_bounds)]
|
error[E0277]: the trait bound `UnsafeCell<u8>: Immutable` is not satisfied
--> tests/ui-nightly/enum.rs:59:10
|
59 | #[derive(Immutable)]
| ^^^^^^^^^ the trait `Immutable` is not implemented for `UnsafeCell<u8>`
|
= note: Consider adding `#[derive(Immutable)]` to `UnsafeCell<u8>`
= help: the following other types implement trait `Immutable`:
&T
&mut T
()
*const T
*mut T
F32<O>
F64<O>
I128<O>
and $N others
= help: see issue #48214
= note: this error originates in the derive macro `Immutable` (in Nightly builds, run with -Z macro-backtrace for more info)
help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
|
9 + #![feature(trivial_bounds)]
|
error[E0277]: the trait bound `NotTryFromBytes: TryFromBytes` is not satisfied
--> tests/ui-nightly/enum.rs:82:10
|
82 | #[derive(TryFromBytes)]
| ^^^^^^^^^^^^ unsatisfied trait bound
|
help: the trait `TryFromBytes` is not implemented for `NotTryFromBytes`
--> tests/ui-nightly/enum.rs:80:1
|
80 | struct NotTryFromBytes;
| ^^^^^^^^^^^^^^^^^^^^^^
= note: Consider adding `#[derive(TryFromBytes)]` to `NotTryFromBytes`
= help: the following other types implement trait `TryFromBytes`:
()
*const T
*mut T
<FromZeros6 as TryFromBytes>::is_bit_valid::___ZerocopyVariantStruct_A
<TryFromBytes3 as TryFromBytes>::is_bit_valid::___ZerocopyVariantStruct_A
AtomicBool
AtomicI16
AtomicI32
and $N others
= help: see issue #48214
= note: this error originates in the derive macro `TryFromBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
|
9 + #![feature(trivial_bounds)]
|
error[E0277]: the trait bound `NotFromZeros: TryFromBytes` is not satisfied
--> tests/ui-nightly/enum.rs:127:10
|
127 | #[derive(FromZeros)]
| ^^^^^^^^^ unsatisfied trait bound
|
help: the trait `TryFromBytes` is not implemented for `NotFromZeros`
--> tests/ui-nightly/enum.rs:125:1
|
125 | struct NotFromZeros;
| ^^^^^^^^^^^^^^^^^^^
= note: Consider adding `#[derive(TryFromBytes)]` to `NotFromZeros`
= help: the following other types implement trait `TryFromBytes`:
()
*const T
*mut T
<FromZeros6 as TryFromBytes>::is_bit_valid::___ZerocopyVariantStruct_A
<TryFromBytes3 as TryFromBytes>::is_bit_valid::___ZerocopyVariantStruct_A
AtomicBool
AtomicI16
AtomicI32
and $N others
= help: see issue #48214
= note: this error originates in the derive macro `FromZeros` (in Nightly builds, run with -Z macro-backtrace for more info)
help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
|
9 + #![feature(trivial_bounds)]
|
error[E0277]: the trait bound `NotFromZeros: FromZeros` is not satisfied
--> tests/ui-nightly/enum.rs:127:10
|
127 | #[derive(FromZeros)]
| ^^^^^^^^^ unsatisfied trait bound
|
help: the trait `FromZeros` is not implemented for `NotFromZeros`
--> tests/ui-nightly/enum.rs:125:1
|
125 | struct NotFromZeros;
| ^^^^^^^^^^^^^^^^^^^
= note: Consider adding `#[derive(FromZeros)]` to `NotFromZeros`
= help: the following other types implement trait `FromZeros`:
()
*const T
*mut T
AtomicBool
AtomicI16
AtomicI32
AtomicI64
AtomicI8
and $N others
= help: see issue #48214
= note: this error originates in the derive macro `FromZeros` (in Nightly builds, run with -Z macro-backtrace for more info)
help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
|
9 + #![feature(trivial_bounds)]
|
error[E0277]: the trait bound `bool: FromBytes` is not satisfied
--> tests/ui-nightly/enum.rs:191:10
|
191 | #[derive(FromBytes)]
| ^^^^^^^^^ the trait `FromBytes` is not implemented for `bool`
|
= note: Consider adding `#[derive(FromBytes)]` to `bool`
= help: the following other types implement trait `FromBytes`:
()
AtomicI16
AtomicI32
AtomicI64
AtomicI8
AtomicIsize
AtomicU16
AtomicU32
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)
help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
|
9 + #![feature(trivial_bounds)]
|
error[E0277]: `IntoBytes1` has 1 total byte(s) of padding
--> tests/ui-nightly/enum.rs:538:10
|
538 | #[derive(IntoBytes)]
| ^^^^^^^^^ types with padding cannot implement `IntoBytes`
|
= note: consider using `zerocopy::Unalign` to lower the alignment of individual fields
= note: consider adding explicit fields where padding would be
= note: consider using `#[repr(packed)]` to remove padding
= help: the trait `PaddingFree<IntoBytes1, 1>` is not implemented for `()`
but trait `PaddingFree<IntoBytes1, 0>` is implemented for it
= help: see issue #48214
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
|
9 + #![feature(trivial_bounds)]
|
error[E0277]: `IntoBytes2` has 3 total byte(s) of padding
--> tests/ui-nightly/enum.rs:549:10
|
549 | #[derive(IntoBytes)]
| ^^^^^^^^^ types with padding cannot implement `IntoBytes`
|
= note: consider using `zerocopy::Unalign` to lower the alignment of individual fields
= note: consider adding explicit fields where padding would be
= note: consider using `#[repr(packed)]` to remove padding
= help: the trait `PaddingFree<IntoBytes2, 3>` is not implemented for `()`
but trait `PaddingFree<IntoBytes2, 0>` is implemented for it
= help: see issue #48214
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
|
9 + #![feature(trivial_bounds)]
|
error[E0277]: `IntoBytes3` has 2 total byte(s) of padding
--> tests/ui-nightly/enum.rs:555:10
|
555 | #[derive(IntoBytes)]
| ^^^^^^^^^ types with padding cannot implement `IntoBytes`
|
= note: consider using `zerocopy::Unalign` to lower the alignment of individual fields
= note: consider adding explicit fields where padding would be
= note: consider using `#[repr(packed)]` to remove padding
= help: the trait `PaddingFree<IntoBytes3, 2>` is not implemented for `()`
but trait `PaddingFree<IntoBytes3, 0>` is implemented for it
= help: see issue #48214
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
|
9 + #![feature(trivial_bounds)]
|
error: generic `Self` types are currently not permitted in anonymous constants
--> tests/ui-nightly/enum.rs:573:10
|
573 | #[derive(IntoBytes)]
| ^^^^^^^^^
|
note: not a concrete type
--> tests/ui-nightly/enum.rs:573:10
|
573 | #[derive(IntoBytes)]
| ^^^^^^^^^
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `bool: FromBytes` is not satisfied
--> tests/ui-nightly/enum.rs:191:10
|
191 | #[derive(FromBytes)]
| ^^^^^^^^^ the trait `FromBytes` is not implemented for `bool`
|
= note: Consider adding `#[derive(FromBytes)]` to `bool`
= help: the following other types implement trait `FromBytes`:
()
AtomicI16
AtomicI32
AtomicI64
AtomicI8
AtomicIsize
AtomicU16
AtomicU32
and $N others
note: required for `FooU8` to implement `FromBytes`
--> tests/ui-nightly/enum.rs:191:10
|
191 | #[derive(FromBytes)]
| ^^^^^^^^^ unsatisfied trait bound introduced in this `derive` macro
note: required by a bound in `assert_is_from_bytes`
--> tests/ui-nightly/enum.rs:191:10
|
191 | #[derive(FromBytes)]
| ^^^^^^^^^ required by this bound in `assert_is_from_bytes`
= note: this error originates in the derive macro `FromBytes` (in Nightly builds, run with -Z macro-backtrace for more info)

View File

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

View File

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

View File

@@ -0,0 +1,85 @@
// Copyright 2019 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.
#[macro_use]
extern crate zerocopy;
#[path = "../include.rs"]
mod util;
use zerocopy::KnownLayout;
use self::util::util::{NotZerocopy, AU16};
fn main() {}
// These tests cause errors which are generated by a later compilation pass than
// the other errors we generate, and so if they're compiled in the same file,
// the compiler will never get to that pass, and so we won't get the errors.
//
// TryFromBytes errors
//
#[derive(TryFromBytes)]
struct TryFromBytes1 {
value: NotZerocopy,
}
//
// FromZeros errors
//
#[derive(FromZeros)]
struct FromZeros1 {
value: NotZerocopy,
}
//
// FromBytes errors
//
#[derive(FromBytes)]
struct FromBytes1 {
value: NotZerocopy,
}
//
// IntoBytes errors
//
#[derive(IntoBytes)]
#[repr(C)]
struct IntoBytes1 {
value: NotZerocopy,
}
//
// Unaligned errors
//
#[derive(Unaligned)]
#[repr(C)]
struct Unaligned1 {
aligned: AU16,
}
// This specifically tests a bug we had in an old version of the code in which
// the trait bound would only be enforced for the first field's type.
#[derive(Unaligned)]
#[repr(C)]
struct Unaligned2 {
unaligned: u8,
aligned: AU16,
}
#[derive(Unaligned)]
#[repr(transparent)]
struct Unaligned3 {
aligned: AU16,
}

View File

@@ -0,0 +1,331 @@
warning: unused import: `zerocopy::KnownLayout`
--> tests/ui-nightly/late_compile_pass.rs:15:5
|
15 | use zerocopy::KnownLayout;
| ^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(unused_imports)]` (part of `#[warn(unused)]`) on by default
error[E0277]: the trait bound `NotZerocopy: zerocopy::TryFromBytes` is not satisfied
--> tests/ui-nightly/late_compile_pass.rs:29:10
|
29 | #[derive(TryFromBytes)]
| ^^^^^^^^^^^^ unsatisfied trait bound
|
help: the trait `zerocopy::TryFromBytes` is not implemented for `NotZerocopy`
--> tests/ui-nightly/../include.rs
|
| pub struct NotZerocopy<T = ()>(pub T);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: Consider adding `#[derive(TryFromBytes)]` to `NotZerocopy`
= help: the following other types implement trait `zerocopy::TryFromBytes`:
()
*const T
*mut T
AU16
AtomicBool
AtomicI16
AtomicI32
AtomicI64
and $N others
= help: see issue #48214
= note: this error originates in the derive macro `TryFromBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
|
9 + #![feature(trivial_bounds)]
|
error[E0277]: the trait bound `NotZerocopy: zerocopy::TryFromBytes` is not satisfied
--> tests/ui-nightly/late_compile_pass.rs:38:10
|
38 | #[derive(FromZeros)]
| ^^^^^^^^^ unsatisfied trait bound
|
help: the trait `zerocopy::TryFromBytes` is not implemented for `NotZerocopy`
--> tests/ui-nightly/../include.rs
|
| pub struct NotZerocopy<T = ()>(pub T);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: Consider adding `#[derive(TryFromBytes)]` to `NotZerocopy`
= help: the following other types implement trait `zerocopy::TryFromBytes`:
()
*const T
*mut T
AU16
AtomicBool
AtomicI16
AtomicI32
AtomicI64
and $N others
= help: see issue #48214
= note: this error originates in the derive macro `FromZeros` (in Nightly builds, run with -Z macro-backtrace for more info)
help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
|
9 + #![feature(trivial_bounds)]
|
error[E0277]: the trait bound `NotZerocopy: FromZeros` is not satisfied
--> tests/ui-nightly/late_compile_pass.rs:38:10
|
38 | #[derive(FromZeros)]
| ^^^^^^^^^ unsatisfied trait bound
|
help: the trait `FromZeros` is not implemented for `NotZerocopy`
--> tests/ui-nightly/../include.rs
|
| pub struct NotZerocopy<T = ()>(pub T);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: Consider adding `#[derive(FromZeros)]` to `NotZerocopy`
= help: the following other types implement trait `FromZeros`:
()
*const T
*mut T
AU16
AtomicBool
AtomicI16
AtomicI32
AtomicI64
and $N others
= help: see issue #48214
= note: this error originates in the derive macro `FromZeros` (in Nightly builds, run with -Z macro-backtrace for more info)
help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
|
9 + #![feature(trivial_bounds)]
|
error[E0277]: the trait bound `NotZerocopy: zerocopy::TryFromBytes` is not satisfied
--> tests/ui-nightly/late_compile_pass.rs:47:10
|
47 | #[derive(FromBytes)]
| ^^^^^^^^^ unsatisfied trait bound
|
help: the trait `zerocopy::TryFromBytes` is not implemented for `NotZerocopy`
--> tests/ui-nightly/../include.rs
|
| pub struct NotZerocopy<T = ()>(pub T);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: Consider adding `#[derive(TryFromBytes)]` to `NotZerocopy`
= help: the following other types implement trait `zerocopy::TryFromBytes`:
()
*const T
*mut T
AU16
AtomicBool
AtomicI16
AtomicI32
AtomicI64
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)
help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
|
9 + #![feature(trivial_bounds)]
|
error[E0277]: the trait bound `NotZerocopy: FromZeros` is not satisfied
--> tests/ui-nightly/late_compile_pass.rs:47:10
|
47 | #[derive(FromBytes)]
| ^^^^^^^^^ unsatisfied trait bound
|
help: the trait `FromZeros` is not implemented for `NotZerocopy`
--> tests/ui-nightly/../include.rs
|
| pub struct NotZerocopy<T = ()>(pub T);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: Consider adding `#[derive(FromZeros)]` to `NotZerocopy`
= help: the following other types implement trait `FromZeros`:
()
*const T
*mut T
AU16
AtomicBool
AtomicI16
AtomicI32
AtomicI64
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)
help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
|
9 + #![feature(trivial_bounds)]
|
error[E0277]: the trait bound `NotZerocopy: zerocopy::FromBytes` is not satisfied
--> tests/ui-nightly/late_compile_pass.rs:47:10
|
47 | #[derive(FromBytes)]
| ^^^^^^^^^ unsatisfied trait bound
|
help: the trait `zerocopy::FromBytes` is not implemented for `NotZerocopy`
--> tests/ui-nightly/../include.rs
|
| pub struct NotZerocopy<T = ()>(pub T);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: Consider adding `#[derive(FromBytes)]` to `NotZerocopy`
= help: the following other types implement trait `zerocopy::FromBytes`:
()
AU16
AtomicI16
AtomicI32
AtomicI64
AtomicI8
AtomicIsize
AtomicU16
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)
help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
|
9 + #![feature(trivial_bounds)]
|
error[E0277]: the trait bound `NotZerocopy: zerocopy::IntoBytes` is not satisfied
--> tests/ui-nightly/late_compile_pass.rs:56:10
|
56 | #[derive(IntoBytes)]
| ^^^^^^^^^ unsatisfied trait bound
|
help: the trait `zerocopy::IntoBytes` is not implemented for `NotZerocopy`
--> tests/ui-nightly/../include.rs
|
| pub struct NotZerocopy<T = ()>(pub T);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: Consider adding `#[derive(IntoBytes)]` to `NotZerocopy`
= help: the following other types implement trait `zerocopy::IntoBytes`:
()
AU16
AtomicBool
AtomicI16
AtomicI32
AtomicI64
AtomicI8
AtomicIsize
and $N others
= help: see issue #48214
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
|
9 + #![feature(trivial_bounds)]
|
error[E0277]: the trait bound `AU16: zerocopy::Unaligned` is not satisfied
--> tests/ui-nightly/late_compile_pass.rs:66:10
|
66 | #[derive(Unaligned)]
| ^^^^^^^^^ unsatisfied trait bound
|
help: the trait `zerocopy::Unaligned` is not implemented for `AU16`
--> tests/ui-nightly/../include.rs
|
| pub struct AU16(pub u16);
| ^^^^^^^^^^^^^^^
= note: Consider adding `#[derive(Unaligned)]` to `AU16`
= help: the following other types implement trait `zerocopy::Unaligned`:
()
AtomicBool
AtomicI8
AtomicU8
Cell<T>
F32<O>
F64<O>
I128<O>
and $N others
= help: see issue #48214
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)
help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
|
9 + #![feature(trivial_bounds)]
|
error[E0277]: the trait bound `AU16: zerocopy::Unaligned` is not satisfied
--> tests/ui-nightly/late_compile_pass.rs:74:10
|
74 | #[derive(Unaligned)]
| ^^^^^^^^^ unsatisfied trait bound
|
help: the trait `zerocopy::Unaligned` is not implemented for `AU16`
--> tests/ui-nightly/../include.rs
|
| pub struct AU16(pub u16);
| ^^^^^^^^^^^^^^^
= note: Consider adding `#[derive(Unaligned)]` to `AU16`
= help: the following other types implement trait `zerocopy::Unaligned`:
()
AtomicBool
AtomicI8
AtomicU8
Cell<T>
F32<O>
F64<O>
I128<O>
and $N others
= help: see issue #48214
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)
help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
|
9 + #![feature(trivial_bounds)]
|
error[E0277]: the trait bound `AU16: zerocopy::Unaligned` is not satisfied
--> tests/ui-nightly/late_compile_pass.rs:81:10
|
81 | #[derive(Unaligned)]
| ^^^^^^^^^ unsatisfied trait bound
|
help: the trait `zerocopy::Unaligned` is not implemented for `AU16`
--> tests/ui-nightly/../include.rs
|
| pub struct AU16(pub u16);
| ^^^^^^^^^^^^^^^
= note: Consider adding `#[derive(Unaligned)]` to `AU16`
= help: the following other types implement trait `zerocopy::Unaligned`:
()
AtomicBool
AtomicI8
AtomicU8
Cell<T>
F32<O>
F64<O>
I128<O>
and $N others
= help: see issue #48214
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)
help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
|
9 + #![feature(trivial_bounds)]
|
error[E0277]: the trait bound `NotZerocopy: zerocopy::FromBytes` is not satisfied
--> tests/ui-nightly/late_compile_pass.rs:47:10
|
47 | #[derive(FromBytes)]
| ^^^^^^^^^ unsatisfied trait bound
|
help: the trait `zerocopy::FromBytes` is not implemented for `NotZerocopy`
--> tests/ui-nightly/../include.rs
|
| pub struct NotZerocopy<T = ()>(pub T);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: Consider adding `#[derive(FromBytes)]` to `NotZerocopy`
= help: the following other types implement trait `zerocopy::FromBytes`:
()
AU16
AtomicI16
AtomicI32
AtomicI64
AtomicI8
AtomicIsize
AtomicU16
and $N others
note: required for `FromBytes1` to implement `zerocopy::FromBytes`
--> tests/ui-nightly/late_compile_pass.rs:47:10
|
47 | #[derive(FromBytes)]
| ^^^^^^^^^ unsatisfied trait bound introduced in this `derive` macro
note: required by a bound in `<FromBytes1 as zerocopy::TryFromBytes>::is_bit_valid::assert_is_from_bytes`
--> tests/ui-nightly/late_compile_pass.rs:47:10
|
47 | #[derive(FromBytes)]
| ^^^^^^^^^ required by this bound in `assert_is_from_bytes`
= note: this error originates in the derive macro `FromBytes` (in Nightly builds, run with -Z macro-backtrace for more info)

View File

@@ -0,0 +1,61 @@
// Copyright 2023 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.
extern crate zerocopy;
use zerocopy::KnownLayout;
fn main() {}
// These tests cause errors which are generated by a later compilation pass than
// the other errors we generate, and so if they're compiled in the same file,
// the compiler will never get to that pass, and so we won't get the errors.
//
// KnownLayout errors
//
fn assert_kl<T: ?Sized + KnownLayout>(_: &T) {}
// | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
// | N | Y | N | N | KL04 |
#[derive(KnownLayout)]
struct KL04<T: ?Sized>(u8, T);
fn test_kl04<T: ?Sized>(kl: &KL04<T>) {
assert_kl(kl);
}
// | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
// | N | Y | Y | N | KL06 |
#[derive(KnownLayout)]
struct KL06<T: ?Sized + KnownLayout>(u8, T);
fn test_kl06<T: ?Sized + KnownLayout>(kl: &KL06<T>) {
assert_kl(kl);
}
// | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
// | Y | Y | N | N | KL12 |
#[derive(KnownLayout)]
#[repr(C)]
struct KL12<T: ?Sized>(u8, T);
fn test_kl12<T: ?Sized>(kl: &KL12<T>) {
assert_kl(kl)
}
// | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
// | Y | Y | N | Y | KL13 |
#[derive(KnownLayout)]
#[repr(C)]
struct KL13<T>(u8, T);
fn test_kl13<T>(t: T) -> impl KnownLayout {
KL13(0u8, t)
}

View File

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

View File

@@ -0,0 +1,254 @@
// Copyright 2019 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.
#[macro_use]
extern crate zerocopy;
#[path = "../include.rs"]
mod util;
use zerocopy::{IntoBytes, KnownLayout};
use self::util::util::AU16;
fn main() {}
//
// KnownLayout errors
//
struct NotKnownLayout;
struct NotKnownLayoutDst([u8]);
// | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
// | N | N | N | N | KL00 |
#[derive(KnownLayout)]
struct KL00(u8, NotKnownLayoutDst);
// | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
// | N | N | Y | N | KL02 |
#[derive(KnownLayout)]
struct KL02(u8, [u8]);
// | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
// | Y | N | N | N | KL08 |
#[derive(KnownLayout)]
#[repr(C)]
struct KL08(u8, NotKnownLayoutDst);
// | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
// | Y | N | N | Y | KL09 |
#[derive(KnownLayout)]
#[repr(C)]
struct KL09(NotKnownLayout, NotKnownLayout);
//
// Immutable errors
//
#[derive(Immutable)]
struct Immutable1 {
a: core::cell::UnsafeCell<()>,
}
#[derive(Immutable)]
struct Immutable2 {
a: [core::cell::UnsafeCell<u8>; 0],
}
//
// TryFromBytes errors
//
#[derive(TryFromBytes)]
#[repr(packed)]
struct TryFromBytesPacked {
foo: AU16,
}
#[derive(TryFromBytes)]
#[repr(packed(1))]
struct TryFromBytesPackedN {
foo: AU16,
}
#[derive(TryFromBytes)]
#[repr(C, packed)]
struct TryFromBytesCPacked {
foo: AU16,
}
#[derive(TryFromBytes)]
#[repr(C, packed(1))]
struct TryFromBytesCPackedN {
foo: AU16,
}
//
// IntoBytes errors
//
// Since `IntoBytes1` has at least one generic parameter, an `IntoBytes` impl is
// emitted in which each field type is given an `Unaligned` bound. Since `foo`'s
// type doesn't implement `Unaligned`, this should fail.
#[derive(IntoBytes)]
#[repr(C)]
struct IntoBytes1<T> {
foo: AU16,
bar: T,
}
#[derive(IntoBytes)]
#[repr(C)]
struct IntoBytes2 {
foo: u8,
bar: AU16,
}
#[derive(IntoBytes)]
#[repr(C, packed(2))]
struct IntoBytes3 {
foo: u8,
// We'd prefer to use AU64 here, but you can't use aligned types in
// packed structs.
bar: u64,
}
type SliceU8 = [u8];
// Padding between `u8` and `SliceU8`. `SliceU8` doesn't syntactically look like
// a slice, so this case is handled by our `Sized` support.
//
// NOTE(#1708): This exists to ensure that our error messages are good when a
// field is unsized.
#[derive(IntoBytes)]
#[repr(C)]
struct IntoBytes4 {
a: u8,
b: SliceU8,
}
// Padding between `u8` and `[u16]`. `[u16]` is syntactically identifiable as a
// slice, so this case is handled by our `repr(C)` slice DST support.
#[derive(IntoBytes)]
#[repr(C)]
struct IntoBytes5 {
a: u8,
b: [u16],
}
// Trailing padding after `[u8]`. `[u8]` is syntactically identifiable as a
// slice, so this case is handled by our `repr(C)` slice DST support.
#[derive(IntoBytes)]
#[repr(C)]
struct IntoBytes6 {
a: u16,
b: [u8],
}
// Padding between `u8` and `u16` and also trailing padding after `[u8]`. `[u8]`
// is syntactically identifiable as a slice, so this case is handled by our
// `repr(C)` slice DST support.
#[derive(IntoBytes)]
#[repr(C)]
struct IntoBytes7 {
a: u8,
b: u16,
c: [u8],
}
#[derive(IntoBytes)]
#[repr(C, C)] // zerocopy-derive conservatively treats these as conflicting reprs
struct IntoBytes8 {
a: u8,
}
#[derive(IntoBytes)]
struct IntoBytes9<T> {
t: T,
}
#[derive(IntoBytes)]
#[repr(packed(2))]
struct IntoBytes10<T> {
t: T,
}
// `repr(C, packed(2))` is not equivalent to `repr(C, packed)`.
#[derive(IntoBytes)]
#[repr(C, packed(2))]
struct IntoBytes11<T> {
t0: T,
// Add a second field to avoid triggering the "repr(C) struct with one
// field" special case.
t1: T,
}
fn is_into_bytes_11<T: IntoBytes>() {
if false {
is_into_bytes_11::<IntoBytes11<AU16>>();
}
}
// `repr(C, align(2))` is not sufficient to guarantee the layout of this type.
#[derive(IntoBytes)]
#[repr(C, align(2))]
struct IntoBytes12<T> {
t: T,
}
//
// Unaligned errors
//
#[derive(Unaligned)]
#[repr(C, align(2))]
struct Unaligned1;
#[derive(Unaligned)]
#[repr(transparent, align(2))]
struct Unaligned2 {
foo: u8,
}
#[derive(Unaligned)]
#[repr(packed, align(2))]
struct Unaligned3;
#[derive(Unaligned)]
#[repr(align(1), align(2))]
struct Unaligned4;
#[derive(Unaligned)]
#[repr(align(2), align(4))]
struct Unaligned5;
#[derive(Unaligned)]
struct Unaligned6;
#[derive(Unaligned)]
#[repr(packed(2))]
struct Unaligned7;
// Test the error message emitted when conflicting reprs appear on different
// lines. On the nightly compiler, this emits a "joint span" that spans both
// problematic repr token trees and everything in between.
#[derive(Copy, Clone)]
#[repr(packed(2), C)]
#[derive(Unaligned)]
#[repr(C, packed(2))]
struct WeirdReprSpan;
#[derive(SplitAt)]
#[repr(C)]
struct SplitAtNotKnownLayout([u8]);
#[derive(SplitAt, KnownLayout)]
#[repr(C)]
struct SplitAtSized(u8);

View File

@@ -0,0 +1,525 @@
error: this conflicts with another representation hint
--> tests/ui-nightly/struct.rs:167:8
|
167 | #[repr(C, C)] // zerocopy-derive conservatively treats these as conflicting reprs
| ^^^^
error: must have a non-align #[repr(...)] attribute in order to guarantee this type's memory layout
--> tests/ui-nightly/struct.rs:172:10
|
172 | #[derive(IntoBytes)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error: must have a non-align #[repr(...)] attribute in order to guarantee this type's memory layout
--> tests/ui-nightly/struct.rs:177:10
|
177 | #[derive(IntoBytes)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error: must have a non-align #[repr(...)] attribute in order to guarantee this type's memory layout
--> tests/ui-nightly/struct.rs:200:10
|
200 | #[derive(IntoBytes)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error: cannot derive `Unaligned` on type with alignment greater than 1
--> tests/ui-nightly/struct.rs:211:11
|
211 | #[repr(C, align(2))]
| ^^^^^^^^
error: this conflicts with another representation hint
--> tests/ui-nightly/struct.rs:215:8
|
215 | #[repr(transparent, align(2))]
| ^^^^^^^^^^^
error: this conflicts with another representation hint
--> tests/ui-nightly/struct.rs:221:8
|
221 | #[repr(packed, align(2))]
| ^^^^^^^^^^^^^^^^
error: this conflicts with another representation hint
--> tests/ui-nightly/struct.rs:225:8
|
225 | #[repr(align(1), align(2))]
| ^^^^^^^^^^^^^^^^^^
error: this conflicts with another representation hint
--> tests/ui-nightly/struct.rs:229:8
|
229 | #[repr(align(2), align(4))]
| ^^^^^^^^^^^^^^^^^^
error: must have #[repr(C)], #[repr(transparent)], or #[repr(packed)] attribute in order to guarantee this type's alignment
--> tests/ui-nightly/struct.rs:232:10
|
232 | #[derive(Unaligned)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)
error: must have #[repr(C)], #[repr(transparent)], or #[repr(packed)] attribute in order to guarantee this type's alignment
--> tests/ui-nightly/struct.rs:235:10
|
235 | #[derive(Unaligned)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)
error: this conflicts with another representation hint
--> tests/ui-nightly/struct.rs:243:19
|
243 | #[repr(packed(2), C)]
| ___________________^
244 | | #[derive(Unaligned)]
245 | | #[repr(C, packed(2))]
| |________^
error[E0692]: transparent struct cannot have other repr hints
--> tests/ui-nightly/struct.rs:215:8
|
215 | #[repr(transparent, align(2))]
| ^^^^^^^^^^^ ^^^^^^^^
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
--> tests/ui-nightly/struct.rs:31:10
|
31 | #[derive(KnownLayout)]
| ^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: within `KL00`, the trait `Sized` is not implemented for `[u8]`
note: required because it appears within the type `KL00`
--> tests/ui-nightly/struct.rs:32:8
|
32 | struct KL00(u8, NotKnownLayoutDst);
| ^^^^
= help: see issue #48214
= note: this error originates in the derive macro `KnownLayout` (in Nightly builds, run with -Z macro-backtrace for more info)
help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
|
9 + #![feature(trivial_bounds)]
|
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
--> tests/ui-nightly/struct.rs:36:10
|
36 | #[derive(KnownLayout)]
| ^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: within `KL02`, the trait `Sized` is not implemented for `[u8]`
note: required because it appears within the type `KL02`
--> tests/ui-nightly/struct.rs:37:8
|
37 | struct KL02(u8, [u8]);
| ^^^^
= help: see issue #48214
= note: this error originates in the derive macro `KnownLayout` (in Nightly builds, run with -Z macro-backtrace for more info)
help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
|
9 + #![feature(trivial_bounds)]
|
error[E0277]: the trait bound `NotKnownLayoutDst: zerocopy::KnownLayout` is not satisfied
--> tests/ui-nightly/struct.rs:41:10
|
41 | #[derive(KnownLayout)]
| ^^^^^^^^^^^ unsatisfied trait bound
|
help: the trait `zerocopy::KnownLayout` is not implemented for `NotKnownLayoutDst`
--> tests/ui-nightly/struct.rs:27:1
|
27 | struct NotKnownLayoutDst([u8]);
| ^^^^^^^^^^^^^^^^^^^^^^^^
= note: Consider adding `#[derive(KnownLayout)]` to `NotKnownLayoutDst`
= help: the following other types implement trait `zerocopy::KnownLayout`:
&T
&mut T
()
*const T
*mut T
AU16
AtomicBool
AtomicI16
and $N others
= help: see issue #48214
= note: this error originates in the derive macro `KnownLayout` (in Nightly builds, run with -Z macro-backtrace for more info)
help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
|
9 + #![feature(trivial_bounds)]
|
error[E0277]: the trait bound `NotKnownLayout: zerocopy::KnownLayout` is not satisfied
--> tests/ui-nightly/struct.rs:47:10
|
47 | #[derive(KnownLayout)]
| ^^^^^^^^^^^ unsatisfied trait bound
|
help: the trait `zerocopy::KnownLayout` is not implemented for `NotKnownLayout`
--> tests/ui-nightly/struct.rs:25:1
|
25 | struct NotKnownLayout;
| ^^^^^^^^^^^^^^^^^^^^^
= note: Consider adding `#[derive(KnownLayout)]` to `NotKnownLayout`
= help: the following other types implement trait `zerocopy::KnownLayout`:
&T
&mut T
()
*const T
*mut T
AU16
AtomicBool
AtomicI16
and $N others
= help: see issue #48214
= note: this error originates in the derive macro `KnownLayout` (in Nightly builds, run with -Z macro-backtrace for more info)
help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
|
9 + #![feature(trivial_bounds)]
|
error[E0277]: the trait bound `UnsafeCell<()>: zerocopy::Immutable` is not satisfied
--> tests/ui-nightly/struct.rs:55:10
|
55 | #[derive(Immutable)]
| ^^^^^^^^^ the trait `zerocopy::Immutable` is not implemented for `UnsafeCell<()>`
|
= note: Consider adding `#[derive(Immutable)]` to `UnsafeCell<()>`
= help: the following other types implement trait `zerocopy::Immutable`:
&T
&mut T
()
*const T
*mut T
AU16
F32<O>
F64<O>
and $N others
= help: see issue #48214
= note: this error originates in the derive macro `Immutable` (in Nightly builds, run with -Z macro-backtrace for more info)
help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
|
9 + #![feature(trivial_bounds)]
|
error[E0277]: the trait bound `UnsafeCell<u8>: zerocopy::Immutable` is not satisfied
--> tests/ui-nightly/struct.rs:60:10
|
60 | #[derive(Immutable)]
| ^^^^^^^^^ the trait `zerocopy::Immutable` is not implemented for `UnsafeCell<u8>`
|
= note: Consider adding `#[derive(Immutable)]` to `UnsafeCell<u8>`
= help: the following other types implement trait `zerocopy::Immutable`:
&T
&mut T
()
*const T
*mut T
AU16
F32<O>
F64<O>
and $N others
= note: required for `[UnsafeCell<u8>; 0]` to implement `zerocopy::Immutable`
= help: see issue #48214
= note: this error originates in the derive macro `Immutable` (in Nightly builds, run with -Z macro-backtrace for more info)
help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
|
9 + #![feature(trivial_bounds)]
|
error[E0588]: packed type cannot transitively contain a `#[repr(align)]` type
--> tests/ui-nightly/struct.rs:71:1
|
71 | struct TryFromBytesPacked {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: `AU16` has a `#[repr(align)]` attribute
--> tests/ui-nightly/../include.rs
|
| pub struct AU16(pub u16);
| ^^^^^^^^^^^^^^^
error[E0588]: packed type cannot transitively contain a `#[repr(align)]` type
--> tests/ui-nightly/struct.rs:77:1
|
77 | struct TryFromBytesPackedN {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: `AU16` has a `#[repr(align)]` attribute
--> tests/ui-nightly/../include.rs
|
| pub struct AU16(pub u16);
| ^^^^^^^^^^^^^^^
error[E0588]: packed type cannot transitively contain a `#[repr(align)]` type
--> tests/ui-nightly/struct.rs:83:1
|
83 | struct TryFromBytesCPacked {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: `AU16` has a `#[repr(align)]` attribute
--> tests/ui-nightly/../include.rs
|
| pub struct AU16(pub u16);
| ^^^^^^^^^^^^^^^
error[E0588]: packed type cannot transitively contain a `#[repr(align)]` type
--> tests/ui-nightly/struct.rs:89:1
|
89 | struct TryFromBytesCPackedN {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: `AU16` has a `#[repr(align)]` attribute
--> tests/ui-nightly/../include.rs
|
| pub struct AU16(pub u16);
| ^^^^^^^^^^^^^^^
error[E0277]: the trait bound `AU16: zerocopy::Unaligned` is not satisfied
--> tests/ui-nightly/struct.rs:100:10
|
100 | #[derive(IntoBytes)]
| ^^^^^^^^^ unsatisfied trait bound
|
help: the trait `zerocopy::Unaligned` is not implemented for `AU16`
--> tests/ui-nightly/../include.rs
|
63 | pub struct AU16(pub u16);
| ^^^^^^^^^^^^^^^
= note: Consider adding `#[derive(Unaligned)]` to `AU16`
= help: the following other types implement trait `zerocopy::Unaligned`:
()
AtomicBool
AtomicI8
AtomicU8
Cell<T>
F32<O>
F64<O>
I128<O>
and $N others
= help: see issue #48214
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
|
9 + #![feature(trivial_bounds)]
|
error[E0277]: `IntoBytes2` has 1 total byte(s) of padding
--> tests/ui-nightly/struct.rs:107:10
|
107 | #[derive(IntoBytes)]
| ^^^^^^^^^ types with padding cannot implement `IntoBytes`
|
= note: consider using `zerocopy::Unalign` to lower the alignment of individual fields
= note: consider adding explicit fields where padding would be
= note: consider using `#[repr(packed)]` to remove padding
= help: the trait `PaddingFree<IntoBytes2, 1>` is not implemented for `()`
but trait `PaddingFree<IntoBytes2, 0>` is implemented for it
= help: see issue #48214
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
|
9 + #![feature(trivial_bounds)]
|
error[E0277]: `IntoBytes3` has 1 total byte(s) of padding
--> tests/ui-nightly/struct.rs:114:10
|
114 | #[derive(IntoBytes)]
| ^^^^^^^^^ types with padding cannot implement `IntoBytes`
|
= note: consider using `zerocopy::Unalign` to lower the alignment of individual fields
= note: consider adding explicit fields where padding would be
= note: consider using `#[repr(packed)]` to remove padding
= help: the trait `PaddingFree<IntoBytes3, 1>` is not implemented for `()`
but trait `PaddingFree<IntoBytes3, 0>` is implemented for it
= help: see issue #48214
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
|
9 + #![feature(trivial_bounds)]
|
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
--> tests/ui-nightly/struct.rs:130:10
|
130 | #[derive(IntoBytes)]
| ^^^^^^^^^ doesn't have a size known at compile-time
|
= help: within `IntoBytes4`, the trait `Sized` is not implemented for `[u8]`
note: required because it appears within the type `IntoBytes4`
--> tests/ui-nightly/struct.rs:132:8
|
132 | struct IntoBytes4 {
| ^^^^^^^^^^
= note: required for `IntoBytes4` to implement `macro_util::__size_of::Sized`
note: required by a bound in `macro_util::__size_of::size_of`
--> $WORKSPACE/src/util/macro_util.rs
|
| pub const fn size_of<T: Sized + ?core::marker::Sized>() -> usize {
| ^^^^^ required by this bound in `size_of`
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: `[u8]` is unsized
--> tests/ui-nightly/struct.rs:134:8
|
134 | b: SliceU8,
| ^^^^^^^ `IntoBytes` needs all field types to be `Sized` in order to determine whether there is padding
|
= help: the trait `Sized` is not implemented for `[u8]`
= note: consider using `#[repr(packed)]` to remove padding
= note: `IntoBytes` does not require the fields of `#[repr(packed)]` types to be `Sized`
= note: required for `[u8]` to implement `macro_util::__size_of::Sized`
note: required by a bound in `macro_util::__size_of::size_of`
--> $WORKSPACE/src/util/macro_util.rs
|
| pub const fn size_of<T: Sized + ?core::marker::Sized>() -> usize {
| ^^^^^ required by this bound in `size_of`
error[E0277]: `IntoBytes5` has one or more padding bytes
--> tests/ui-nightly/struct.rs:139:10
|
139 | #[derive(IntoBytes)]
| ^^^^^^^^^ types with padding cannot implement `IntoBytes`
|
= note: consider using `zerocopy::Unalign` to lower the alignment of individual fields
= note: consider adding explicit fields where padding would be
= note: consider using `#[repr(packed)]` to remove padding
= help: the trait `DynamicPaddingFree<IntoBytes5, true>` is not implemented for `()`
but trait `DynamicPaddingFree<IntoBytes5, false>` is implemented for it
= help: see issue #48214
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
|
9 + #![feature(trivial_bounds)]
|
error[E0277]: `IntoBytes6` has one or more padding bytes
--> tests/ui-nightly/struct.rs:148:10
|
148 | #[derive(IntoBytes)]
| ^^^^^^^^^ types with padding cannot implement `IntoBytes`
|
= note: consider using `zerocopy::Unalign` to lower the alignment of individual fields
= note: consider adding explicit fields where padding would be
= note: consider using `#[repr(packed)]` to remove padding
= help: the trait `DynamicPaddingFree<IntoBytes6, true>` is not implemented for `()`
but trait `DynamicPaddingFree<IntoBytes6, false>` is implemented for it
= help: see issue #48214
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
|
9 + #![feature(trivial_bounds)]
|
error[E0277]: `IntoBytes7` has one or more padding bytes
--> tests/ui-nightly/struct.rs:158:10
|
158 | #[derive(IntoBytes)]
| ^^^^^^^^^ types with padding cannot implement `IntoBytes`
|
= note: consider using `zerocopy::Unalign` to lower the alignment of individual fields
= note: consider adding explicit fields where padding would be
= note: consider using `#[repr(packed)]` to remove padding
= help: the trait `DynamicPaddingFree<IntoBytes7, true>` is not implemented for `()`
but trait `DynamicPaddingFree<IntoBytes7, false>` is implemented for it
= help: see issue #48214
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
|
9 + #![feature(trivial_bounds)]
|
error[E0587]: type has conflicting packed and align representation hints
--> tests/ui-nightly/struct.rs:222:1
|
222 | struct Unaligned3;
| ^^^^^^^^^^^^^^^^^
error[E0277]: the trait bound `SplitAtNotKnownLayout: zerocopy::KnownLayout` is not satisfied
--> tests/ui-nightly/struct.rs:248:10
|
248 | #[derive(SplitAt)]
| ^^^^^^^ unsatisfied trait bound
|
help: the trait `zerocopy::KnownLayout` is not implemented for `SplitAtNotKnownLayout`
--> tests/ui-nightly/struct.rs:250:1
|
250 | struct SplitAtNotKnownLayout([u8]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: Consider adding `#[derive(KnownLayout)]` to `SplitAtNotKnownLayout`
= help: the following other types implement trait `zerocopy::KnownLayout`:
&T
&mut T
()
*const T
*mut T
AU16
AtomicBool
AtomicI16
and $N others
note: required by a bound in `SplitAt`
--> $WORKSPACE/src/split_at.rs
|
61 | pub unsafe trait SplitAt: KnownLayout<PointerMetadata = usize> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `SplitAt`
= note: this error originates in the derive macro `SplitAt` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `u8: SplitAt` is not satisfied
--> tests/ui-nightly/struct.rs:252:10
|
252 | #[derive(SplitAt, KnownLayout)]
| ^^^^^^^ the trait `SplitAt` is not implemented for `u8`
|
= note: Consider adding `#[derive(SplitAt)]` to `u8`
= help: the following other types implement trait `SplitAt`:
SplitAtNotKnownLayout
SplitAtSized
[T]
= help: see issue #48214
= note: this error originates in the derive macro `SplitAt` (in Nightly builds, run with -Z macro-backtrace for more info)
help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
|
9 + #![feature(trivial_bounds)]
|
error[E0277]: the trait bound `AU16: zerocopy::Unaligned` is not satisfied
--> tests/ui-nightly/struct.rs:195:28
|
195 | is_into_bytes_11::<IntoBytes11<AU16>>();
| ^^^^^^^^^^^^^^^^^ unsatisfied trait bound
|
help: the trait `zerocopy::Unaligned` is not implemented for `AU16`
--> tests/ui-nightly/../include.rs
|
63 | pub struct AU16(pub u16);
| ^^^^^^^^^^^^^^^
= note: Consider adding `#[derive(Unaligned)]` to `AU16`
= help: the following other types implement trait `zerocopy::Unaligned`:
()
AtomicBool
AtomicI8
AtomicU8
Cell<T>
F32<O>
F64<O>
I128<O>
and $N others
note: required for `IntoBytes11<AU16>` to implement `zerocopy::IntoBytes`
--> tests/ui-nightly/struct.rs:184:10
|
184 | #[derive(IntoBytes)]
| ^^^^^^^^^ unsatisfied trait bound introduced in this `derive` macro
note: required by a bound in `is_into_bytes_11`
--> tests/ui-nightly/struct.rs:193:24
|
193 | fn is_into_bytes_11<T: IntoBytes>() {
| ^^^^^^^^^ required by this bound in `is_into_bytes_11`
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)

View File

@@ -0,0 +1,109 @@
// Copyright 2019 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.
#[macro_use]
extern crate zerocopy;
#[path = "../include.rs"]
mod util;
use std::mem::ManuallyDrop;
use self::util::util::AU16;
fn main() {}
//
// Immutable errors
//
#[derive(Immutable)]
union Immutable1 {
a: ManuallyDrop<core::cell::UnsafeCell<()>>,
}
//
// IntoBytes errors
//
#[derive(IntoBytes)]
#[repr(C)]
union IntoBytes1<T> {
foo: ManuallyDrop<T>,
}
#[derive(IntoBytes)]
#[repr(C)]
union IntoBytes2 {
foo: u8,
bar: [u8; 2],
}
// Need a `repr` attribute
#[derive(IntoBytes)]
union IntoBytes3 {
foo: u8,
}
// `repr(packed(2))` isn't equivalent to `repr(packed)`
#[derive(IntoBytes)]
#[repr(packed(2))]
union IntoBytes4 {
foo: u8,
}
//
// Unaligned errors
//
#[derive(Unaligned)]
#[repr(C, align(2))]
union Unaligned1 {
foo: i16,
bar: AU16,
}
// Transparent unions are unstable; see issue #60405
// <https://github.com/rust-lang/rust/issues/60405> for more information.
// #[derive(Unaligned)]
// #[repr(transparent, align(2))]
// union Unaligned2 {
// foo: u8,
// }
#[derive(Unaligned)]
#[repr(packed, align(2))]
union Unaligned3 {
foo: u8,
}
#[derive(Unaligned)]
#[repr(align(1), align(2))]
struct Unaligned4 {
foo: u8,
}
#[derive(Unaligned)]
#[repr(align(2), align(4))]
struct Unaligned5 {
foo: u8,
}
#[derive(Unaligned)]
union Unaligned6 {
foo: i16,
bar: AU16,
}
#[derive(Unaligned)]
#[repr(packed(2))]
union Unaligned7 {
foo: i16,
bar: AU16,
}

View File

@@ -0,0 +1,138 @@
error: unsupported on types with type parameters
--> tests/ui-nightly/union.rs:34:10
|
34 | #[derive(IntoBytes)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error: must be #[repr(C)], #[repr(packed)], or #[repr(transparent)]
--> tests/ui-nightly/union.rs:48:10
|
48 | #[derive(IntoBytes)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error: must be #[repr(C)], #[repr(packed)], or #[repr(transparent)]
--> tests/ui-nightly/union.rs:54:10
|
54 | #[derive(IntoBytes)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error: cannot derive `Unaligned` on type with alignment greater than 1
--> tests/ui-nightly/union.rs:65:11
|
65 | #[repr(C, align(2))]
| ^^^^^^^^
error: this conflicts with another representation hint
--> tests/ui-nightly/union.rs:81:8
|
81 | #[repr(packed, align(2))]
| ^^^^^^^^^^^^^^^^
error: this conflicts with another representation hint
--> tests/ui-nightly/union.rs:87:8
|
87 | #[repr(align(1), align(2))]
| ^^^^^^^^^^^^^^^^^^
error: this conflicts with another representation hint
--> tests/ui-nightly/union.rs:93:8
|
93 | #[repr(align(2), align(4))]
| ^^^^^^^^^^^^^^^^^^
error: must have #[repr(C)], #[repr(transparent)], or #[repr(packed)] attribute in order to guarantee this type's alignment
--> tests/ui-nightly/union.rs:98:10
|
98 | #[derive(Unaligned)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)
error: must have #[repr(C)], #[repr(transparent)], or #[repr(packed)] attribute in order to guarantee this type's alignment
--> tests/ui-nightly/union.rs:104:10
|
104 | #[derive(Unaligned)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)
warning: unexpected `cfg` condition name: `zerocopy_derive_union_into_bytes`
--> tests/ui-nightly/union.rs:40:10
|
40 | #[derive(IntoBytes)]
| ^^^^^^^^^
|
= help: expected names are: `docsrs`, `feature`, and `test` and 31 more
= note: using a cfg inside a derive macro will use the cfgs from the destination crate and not the ones from the defining crate
= help: try referring to `IntoBytes` crate for guidance on how handle this unexpected cfg
= help: the derive macro `IntoBytes` may come from an old version of the `zerocopy_derive` crate, try updating your dependency with `cargo update -p zerocopy_derive`
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg/cargo-specifics.html> for more information about checking conditional configuration
= note: `#[warn(unexpected_cfgs)]` on by default
= note: this warning originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `UnsafeCell<()>: zerocopy::Immutable` is not satisfied
--> tests/ui-nightly/union.rs:25:10
|
25 | #[derive(Immutable)]
| ^^^^^^^^^ the trait `zerocopy::Immutable` is not implemented for `UnsafeCell<()>`
|
= note: Consider adding `#[derive(Immutable)]` to `UnsafeCell<()>`
= help: the following other types implement trait `zerocopy::Immutable`:
&T
&mut T
()
*const T
*mut T
AU16
F32<O>
F64<O>
and $N others
= note: required for `ManuallyDrop<UnsafeCell<()>>` to implement `zerocopy::Immutable`
= help: see issue #48214
= note: this error originates in the derive macro `Immutable` (in Nightly builds, run with -Z macro-backtrace for more info)
help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
|
9 + #![feature(trivial_bounds)]
|
error[E0277]: `IntoBytes2` has 1 total byte(s) of padding
--> tests/ui-nightly/union.rs:40:10
|
40 | #[derive(IntoBytes)]
| ^^^^^^^^^ types with padding cannot implement `IntoBytes`
|
= note: consider using `zerocopy::Unalign` to lower the alignment of individual fields
= note: consider adding explicit fields where padding would be
= note: consider using `#[repr(packed)]` to remove padding
= help: the trait `PaddingFree<IntoBytes2, 1>` is not implemented for `()`
but trait `PaddingFree<IntoBytes2, 0>` is implemented for it
= help: see issue #48214
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
|
9 + #![feature(trivial_bounds)]
|
error[E0587]: type has conflicting packed and align representation hints
--> tests/ui-nightly/union.rs:82:1
|
82 | union Unaligned3 {
| ^^^^^^^^^^^^^^^^
error[E0588]: packed type cannot transitively contain a `#[repr(align)]` type
--> tests/ui-nightly/union.rs:106:1
|
106 | union Unaligned7 {
| ^^^^^^^^^^^^^^^^
|
note: `AU16` has a `#[repr(align)]` attribute
--> tests/ui-nightly/../include.rs
|
63 | pub struct AU16(pub u16);
| ^^^^^^^^^^^^^^^

View File

@@ -0,0 +1,26 @@
// Copyright 2024 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.
//! See: https://github.com/google/zerocopy/issues/553
//! zerocopy must still allow derives of deprecated types.
//! This test has a hand-written impl of a deprecated type, and should result in a compilation
//! error. If zerocopy does not tack an allow(deprecated) annotation onto its impls, then this
//! test will fail because more than one compile error will be generated.
#![deny(deprecated)]
extern crate zerocopy;
use zerocopy::IntoBytes;
#[derive(IntoBytes)]
#[repr(C)]
union Foo {
a: u8,
}
fn main() {}

View File

@@ -0,0 +1,22 @@
error: requires --cfg zerocopy_derive_union_into_bytes;
please let us know you use this feature: https://github.com/google/zerocopy/discussions/1802
--> tests/ui-nightly/union_into_bytes_cfg/union_into_bytes_cfg.rs:20:10
|
20 | #[derive(IntoBytes)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
warning: unexpected `cfg` condition name: `zerocopy_derive_union_into_bytes`
--> tests/ui-nightly/union_into_bytes_cfg/union_into_bytes_cfg.rs:20:10
|
20 | #[derive(IntoBytes)]
| ^^^^^^^^^
|
= help: expected names are: `docsrs`, `feature`, and `test` and 31 more
= note: using a cfg inside a derive macro will use the cfgs from the destination crate and not the ones from the defining crate
= help: try referring to `IntoBytes` crate for guidance on how handle this unexpected cfg
= help: the derive macro `IntoBytes` may come from an old version of the `zerocopy_derive` crate, try updating your dependency with `cargo update -p zerocopy_derive`
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg/cargo-specifics.html> for more information about checking conditional configuration
= note: `#[warn(unexpected_cfgs)]` on by default
= note: this warning originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)

View File

@@ -0,0 +1,38 @@
// Copyright 2019 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.
extern crate zerocopy;
#[path = "../include.rs"]
mod util;
use core::marker::PhantomData;
use zerocopy::{FromBytes, FromZeros, IntoBytes, TryFromBytes, Unaligned};
use self::util::util::NotZerocopy;
fn main() {}
// Test generic transparent structs
#[derive(IntoBytes, 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.
util_assert_impl_all!(TransparentStruct<NotZerocopy>: TryFromBytes);
util_assert_impl_all!(TransparentStruct<NotZerocopy>: FromZeros);
util_assert_impl_all!(TransparentStruct<NotZerocopy>: FromBytes);
util_assert_impl_all!(TransparentStruct<NotZerocopy>: IntoBytes);
util_assert_impl_all!(TransparentStruct<NotZerocopy>: Unaligned);

View File

@@ -0,0 +1,144 @@
error[E0277]: the trait bound `NotZerocopy: zerocopy::TryFromBytes` is not satisfied
--> tests/ui-stable/derive_transparent.rs:34:23
|
34 | util_assert_impl_all!(TransparentStruct<NotZerocopy>: TryFromBytes);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `zerocopy::TryFromBytes` is not implemented for `NotZerocopy`
|
= note: Consider adding `#[derive(TryFromBytes)]` to `NotZerocopy`
= help: the following other types implement trait `zerocopy::TryFromBytes`:
()
*const T
*mut T
AU16
AtomicBool
AtomicI16
AtomicI32
AtomicI64
and $N others
note: required for `TransparentStruct<NotZerocopy>` to implement `zerocopy::TryFromBytes`
--> tests/ui-stable/derive_transparent.rs:24:21
|
24 | #[derive(IntoBytes, FromBytes, Unaligned)]
| ^^^^^^^^^ unsatisfied trait bound introduced in this `derive` macro
note: required by a bound in `_::{closure#0}::_::{closure#0}::assert_impl_all`
--> tests/ui-stable/derive_transparent.rs:34:1
|
34 | util_assert_impl_all!(TransparentStruct<NotZerocopy>: TryFromBytes);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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 `util_assert_impl_all` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `NotZerocopy: FromZeros` is not satisfied
--> tests/ui-stable/derive_transparent.rs:35:23
|
35 | util_assert_impl_all!(TransparentStruct<NotZerocopy>: FromZeros);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `FromZeros` is not implemented for `NotZerocopy`
|
= note: Consider adding `#[derive(FromZeros)]` to `NotZerocopy`
= help: the following other types implement trait `FromZeros`:
()
*const T
*mut T
AU16
AtomicBool
AtomicI16
AtomicI32
AtomicI64
and $N others
note: required for `TransparentStruct<NotZerocopy>` to implement `FromZeros`
--> tests/ui-stable/derive_transparent.rs:24:21
|
24 | #[derive(IntoBytes, FromBytes, Unaligned)]
| ^^^^^^^^^ unsatisfied trait bound introduced in this `derive` macro
note: required by a bound in `_::{closure#0}::_::{closure#0}::assert_impl_all`
--> tests/ui-stable/derive_transparent.rs:35:1
|
35 | util_assert_impl_all!(TransparentStruct<NotZerocopy>: FromZeros);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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 `util_assert_impl_all` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `NotZerocopy: zerocopy::FromBytes` is not satisfied
--> tests/ui-stable/derive_transparent.rs:36:23
|
36 | util_assert_impl_all!(TransparentStruct<NotZerocopy>: FromBytes);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `zerocopy::FromBytes` is not implemented for `NotZerocopy`
|
= note: Consider adding `#[derive(FromBytes)]` to `NotZerocopy`
= help: the following other types implement trait `zerocopy::FromBytes`:
()
AU16
AtomicI16
AtomicI32
AtomicI64
AtomicI8
AtomicIsize
AtomicU16
and $N others
note: required for `TransparentStruct<NotZerocopy>` to implement `zerocopy::FromBytes`
--> tests/ui-stable/derive_transparent.rs:24:21
|
24 | #[derive(IntoBytes, FromBytes, Unaligned)]
| ^^^^^^^^^ unsatisfied trait bound introduced in this `derive` macro
note: required by a bound in `_::{closure#0}::_::{closure#0}::assert_impl_all`
--> tests/ui-stable/derive_transparent.rs:36:1
|
36 | util_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 `util_assert_impl_all` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `NotZerocopy: zerocopy::IntoBytes` is not satisfied
--> tests/ui-stable/derive_transparent.rs:37:23
|
37 | util_assert_impl_all!(TransparentStruct<NotZerocopy>: IntoBytes);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `zerocopy::IntoBytes` is not implemented for `NotZerocopy`
|
= note: Consider adding `#[derive(IntoBytes)]` to `NotZerocopy`
= help: the following other types implement trait `zerocopy::IntoBytes`:
()
AU16
AtomicBool
AtomicI16
AtomicI32
AtomicI64
AtomicI8
AtomicIsize
and $N others
note: required for `TransparentStruct<NotZerocopy>` to implement `zerocopy::IntoBytes`
--> tests/ui-stable/derive_transparent.rs:24:10
|
24 | #[derive(IntoBytes, FromBytes, Unaligned)]
| ^^^^^^^^^ unsatisfied trait bound introduced in this `derive` macro
note: required by a bound in `_::{closure#0}::_::{closure#0}::assert_impl_all`
--> tests/ui-stable/derive_transparent.rs:37:1
|
37 | util_assert_impl_all!(TransparentStruct<NotZerocopy>: IntoBytes);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `assert_impl_all`
= note: this error originates in the derive macro `IntoBytes` which comes from the expansion of the macro `util_assert_impl_all` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `NotZerocopy: zerocopy::Unaligned` is not satisfied
--> tests/ui-stable/derive_transparent.rs:38:23
|
38 | util_assert_impl_all!(TransparentStruct<NotZerocopy>: Unaligned);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `zerocopy::Unaligned` is not implemented for `NotZerocopy`
|
= note: Consider adding `#[derive(Unaligned)]` to `NotZerocopy`
= help: the following other types implement trait `zerocopy::Unaligned`:
()
AtomicBool
AtomicI8
AtomicU8
Cell<T>
F32<O>
F64<O>
I128<O>
and $N others
note: required for `TransparentStruct<NotZerocopy>` to implement `zerocopy::Unaligned`
--> tests/ui-stable/derive_transparent.rs:24:32
|
24 | #[derive(IntoBytes, FromBytes, Unaligned)]
| ^^^^^^^^^ unsatisfied trait bound introduced in this `derive` macro
note: required by a bound in `_::{closure#0}::_::{closure#0}::assert_impl_all`
--> tests/ui-stable/derive_transparent.rs:38:1
|
38 | util_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 `util_assert_impl_all` (in Nightly builds, run with -Z macro-backtrace for more info)

View File

@@ -0,0 +1,577 @@
// Copyright 2019 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.
#[macro_use]
extern crate zerocopy;
fn main() {}
//
// Generic errors
//
#[derive(FromBytes)]
#[repr("foo")]
enum Generic1 {
A,
}
#[derive(FromBytes)]
#[repr(foo)]
enum Generic2 {
A,
}
#[derive(FromBytes)]
#[repr(transparent)]
enum Generic3 {
A,
}
#[derive(FromBytes)]
#[repr(u8, u16)]
enum Generic4 {
A,
}
#[derive(FromBytes)]
enum Generic5 {
A,
}
//
// Immutable errors
//
#[derive(Immutable)]
enum Immutable1 {
A(core::cell::UnsafeCell<()>),
}
#[derive(Immutable)]
enum Never {}
#[derive(Immutable)]
enum Immutable2 {
Uninhabited(Never, core::cell::UnsafeCell<u8>),
Inhabited(u8),
}
//
// TryFromBytes errors
//
#[derive(TryFromBytes)]
enum TryFromBytes1 {
A,
}
#[derive(TryFromBytes)]
enum TryFromBytes2 {
A,
B(u8),
}
struct NotTryFromBytes;
#[derive(TryFromBytes)]
#[repr(u8)]
enum TryFromBytes3 {
A(NotTryFromBytes),
}
//
// FromZeros errors
//
#[derive(FromZeros)]
enum FromZeros1 {
A(u8),
}
#[derive(FromZeros)]
enum FromZeros2 {
A,
B(u8),
}
#[derive(FromZeros)]
enum FromZeros3 {
A = 1,
B,
}
#[derive(FromZeros)]
#[repr(u8)]
enum FromZeros4 {
A = 1,
B = 2,
}
const NEGATIVE_ONE: i8 = -1;
#[derive(FromZeros)]
#[repr(i8)]
enum FromZeros5 {
A = NEGATIVE_ONE,
B,
}
struct NotFromZeros;
#[derive(FromZeros)]
#[repr(u8)]
enum FromZeros6 {
A(NotFromZeros),
}
#[derive(FromZeros)]
#[repr(u8)]
enum FromZeros7 {
A = 1,
B(NotFromZeros),
}
//
// FromBytes errors
//
#[derive(FromBytes)]
enum FromBytes1 {
A,
}
#[derive(FromBytes)]
#[repr(C)]
enum FromBytes2 {
A,
}
#[derive(FromBytes)]
#[repr(usize)]
enum FromBytes3 {
A,
}
#[derive(FromBytes)]
#[repr(isize)]
enum FromBytes4 {
A,
}
#[derive(FromBytes)]
#[repr(u32)]
enum FromBytes5 {
A,
}
#[derive(FromBytes)]
#[repr(i32)]
enum FromBytes6 {
A,
}
#[derive(FromBytes)]
#[repr(u64)]
enum FromBytes7 {
A,
}
#[derive(FromBytes)]
#[repr(i64)]
enum FromBytes8 {
A,
}
#[derive(FromBytes)]
#[repr(u8)]
enum FooU8 {
Variant0,
Variant1,
Variant2,
Variant3,
Variant4,
Variant5,
Variant6,
Variant7,
Variant8,
Variant9,
Variant10,
Variant11,
Variant12,
Variant13,
Variant14,
Variant15,
Variant16,
Variant17,
Variant18,
Variant19,
Variant20,
Variant21,
Variant22,
Variant23,
Variant24,
Variant25,
Variant26,
Variant27,
Variant28,
Variant29,
Variant30,
Variant31,
Variant32,
Variant33,
Variant34,
Variant35,
Variant36,
Variant37,
Variant38,
Variant39,
Variant40,
Variant41,
Variant42,
Variant43,
Variant44,
Variant45,
Variant46,
Variant47,
Variant48,
Variant49,
Variant50,
Variant51,
Variant52,
Variant53,
Variant54,
Variant55,
Variant56,
Variant57,
Variant58,
Variant59,
Variant60,
Variant61,
Variant62,
Variant63,
Variant64,
Variant65,
Variant66,
Variant67,
Variant68,
Variant69,
Variant70,
Variant71,
Variant72,
Variant73,
Variant74,
Variant75,
Variant76,
Variant77,
Variant78,
Variant79,
Variant80,
Variant81,
Variant82,
Variant83,
Variant84,
Variant85,
Variant86,
Variant87,
Variant88,
Variant89,
Variant90,
Variant91,
Variant92,
Variant93,
Variant94,
Variant95,
Variant96,
Variant97,
Variant98,
Variant99,
Variant100,
Variant101,
Variant102,
Variant103,
Variant104,
Variant105,
Variant106,
Variant107,
Variant108,
Variant109,
Variant110,
Variant111,
Variant112,
Variant113,
Variant114,
Variant115,
Variant116,
Variant117,
Variant118,
Variant119,
Variant120,
Variant121,
Variant122,
Variant123,
Variant124,
Variant125,
Variant126,
Variant127,
Variant128,
Variant129,
Variant130,
Variant131,
Variant132,
Variant133,
Variant134,
Variant135,
Variant136,
Variant137,
Variant138,
Variant139,
Variant140,
Variant141,
Variant142,
Variant143,
Variant144,
Variant145,
Variant146,
Variant147,
Variant148,
Variant149,
Variant150,
Variant151,
Variant152,
Variant153,
Variant154,
Variant155,
Variant156,
Variant157,
Variant158,
Variant159,
Variant160,
Variant161,
Variant162,
Variant163,
Variant164,
Variant165,
Variant166,
Variant167,
Variant168,
Variant169,
Variant170,
Variant171,
Variant172,
Variant173,
Variant174,
Variant175,
Variant176,
Variant177,
Variant178,
Variant179,
Variant180,
Variant181,
Variant182,
Variant183,
Variant184,
Variant185,
Variant186,
Variant187,
Variant188,
Variant189,
Variant190,
Variant191,
Variant192,
Variant193,
Variant194,
Variant195,
Variant196,
Variant197,
Variant198,
Variant199,
Variant200,
Variant201,
Variant202,
Variant203,
Variant204,
Variant205,
Variant206,
Variant207,
Variant208,
Variant209,
Variant210,
Variant211,
Variant212,
Variant213,
Variant214,
Variant215,
Variant216,
Variant217,
Variant218,
Variant219,
Variant220,
Variant221,
Variant222,
Variant223,
Variant224,
Variant225,
Variant226,
Variant227,
Variant228,
Variant229,
Variant230,
Variant231,
Variant232,
Variant233,
Variant234,
Variant235,
Variant236,
Variant237,
Variant238,
Variant239,
Variant240,
Variant241,
Variant242,
Variant243,
Variant244,
Variant245,
Variant246,
Variant247,
Variant248,
Variant249,
Variant250,
Variant251,
Variant252,
Variant253,
Variant254,
Variant255(bool),
}
//
// Unaligned errors
//
#[derive(Unaligned)]
#[repr(C)]
enum Unaligned1 {
A,
}
#[derive(Unaligned)]
#[repr(u16)]
enum Unaligned2 {
A,
}
#[derive(Unaligned)]
#[repr(i16)]
enum Unaligned3 {
A,
}
#[derive(Unaligned)]
#[repr(u32)]
enum Unaligned4 {
A,
}
#[derive(Unaligned)]
#[repr(i32)]
enum Unaligned5 {
A,
}
#[derive(Unaligned)]
#[repr(u64)]
enum Unaligned6 {
A,
}
#[derive(Unaligned)]
#[repr(i64)]
enum Unaligned7 {
A,
}
#[derive(Unaligned)]
#[repr(usize)]
enum Unaligned8 {
A,
}
#[derive(Unaligned)]
#[repr(isize)]
enum Unaligned9 {
A,
}
#[derive(Unaligned)]
#[repr(u8, align(2))]
enum Unaligned10 {
A,
}
#[derive(Unaligned)]
#[repr(i8, align(2))]
enum Unaligned11 {
A,
}
#[derive(Unaligned)]
#[repr(align(1), align(2))]
enum Unaligned12 {
A,
}
#[derive(Unaligned)]
#[repr(align(2), align(4))]
enum Unaligned13 {
A,
}
//
// IntoBytes errors
//
#[derive(IntoBytes)]
#[repr(u8)]
enum IntoBytes1 {
A,
B(u8),
}
#[derive(IntoBytes)]
#[repr(C, align(4))]
struct Align4IntoBytes(u32);
#[derive(IntoBytes)]
#[repr(u8)]
enum IntoBytes2 {
A(Align4IntoBytes),
}
#[derive(IntoBytes)]
#[repr(u32)]
enum IntoBytes3 {
A(u32),
B(u16),
}
#[derive(IntoBytes)]
enum IntoBytes4 {
A(u32),
B(u16),
}
#[derive(IntoBytes)]
enum IntoBytes5 {
A(u32),
}
#[derive(IntoBytes)]
#[repr(u8)]
enum IntoBytes6<T> {
A(T),
}

View File

@@ -0,0 +1,502 @@
error: unrecognized representation hint
--> tests/ui-stable/enum.rs:19:8
|
19 | #[repr("foo")]
| ^^^^^
error: unrecognized representation hint
--> tests/ui-stable/enum.rs:25:8
|
25 | #[repr(foo)]
| ^^^
error: must have #[repr(C)] or #[repr(Int)] attribute in order to guarantee this type's memory layout
--> tests/ui-stable/enum.rs:30:10
|
30 | #[derive(FromBytes)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `FromBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error: this conflicts with another representation hint
--> tests/ui-stable/enum.rs:37:12
|
37 | #[repr(u8, u16)]
| ^^^
error: must have #[repr(C)] or #[repr(Int)] attribute in order to guarantee this type's memory layout
--> tests/ui-stable/enum.rs:42:10
|
42 | #[derive(FromBytes)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `FromBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error: must have #[repr(C)] or #[repr(Int)] attribute in order to guarantee this type's memory layout
--> tests/ui-stable/enum.rs:69:10
|
69 | #[derive(TryFromBytes)]
| ^^^^^^^^^^^^
|
= note: this error originates in the derive macro `TryFromBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error: must have #[repr(C)] or #[repr(Int)] attribute in order to guarantee this type's memory layout
--> tests/ui-stable/enum.rs:74:10
|
74 | #[derive(TryFromBytes)]
| ^^^^^^^^^^^^
|
= note: this error originates in the derive macro `TryFromBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error: must have #[repr(C)] or #[repr(Int)] attribute in order to guarantee this type's memory layout
--> tests/ui-stable/enum.rs:92:10
|
92 | #[derive(FromZeros)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `FromZeros` (in Nightly builds, run with -Z macro-backtrace for more info)
error: must have #[repr(C)] or #[repr(Int)] attribute in order to guarantee this type's memory layout
--> tests/ui-stable/enum.rs:97:10
|
97 | #[derive(FromZeros)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `FromZeros` (in Nightly builds, run with -Z macro-backtrace for more info)
error: must have #[repr(C)] or #[repr(Int)] attribute in order to guarantee this type's memory layout
--> tests/ui-stable/enum.rs:103:10
|
103 | #[derive(FromZeros)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `FromZeros` (in Nightly builds, run with -Z macro-backtrace for more info)
error: FromZeros only supported on enums with a variant that has a discriminant of `0`
--> tests/ui-stable/enum.rs:110:1
|
110 | / #[repr(u8)]
111 | | enum FromZeros4 {
112 | | A = 1,
113 | | B = 2,
114 | | }
| |_^
error: FromZeros only supported on enums with a variant that has a discriminant of `0`
help: This enum has discriminants which are not literal integers. One of those may define or imply which variant has a discriminant of zero. Use a literal integer to define or imply the variant with a discriminant of zero.
--> tests/ui-stable/enum.rs:119:1
|
119 | / #[repr(i8)]
120 | | enum FromZeros5 {
121 | | A = NEGATIVE_ONE,
122 | | B,
123 | | }
| |_^
error: FromZeros only supported on enums with a variant that has a discriminant of `0`
--> tests/ui-stable/enum.rs:134:1
|
134 | / #[repr(u8)]
135 | | enum FromZeros7 {
136 | | A = 1,
137 | | B(NotFromZeros),
138 | | }
| |_^
error: must have #[repr(C)] or #[repr(Int)] attribute in order to guarantee this type's memory layout
--> tests/ui-stable/enum.rs:144:10
|
144 | #[derive(FromBytes)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `FromBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error: `FromBytes` only supported on enums with `#[repr(...)]` attributes `u8`, `i8`, `u16`, or `i16`
--> tests/ui-stable/enum.rs:150:8
|
150 | #[repr(C)]
| ^
error: `FromBytes` only supported on enums with `#[repr(...)]` attributes `u8`, `i8`, `u16`, or `i16`
--> tests/ui-stable/enum.rs:156:8
|
156 | #[repr(usize)]
| ^^^^^
error: `FromBytes` only supported on enums with `#[repr(...)]` attributes `u8`, `i8`, `u16`, or `i16`
--> tests/ui-stable/enum.rs:162:8
|
162 | #[repr(isize)]
| ^^^^^
error: `FromBytes` only supported on enums with `#[repr(...)]` attributes `u8`, `i8`, `u16`, or `i16`
--> tests/ui-stable/enum.rs:168:8
|
168 | #[repr(u32)]
| ^^^
error: `FromBytes` only supported on enums with `#[repr(...)]` attributes `u8`, `i8`, `u16`, or `i16`
--> tests/ui-stable/enum.rs:174:8
|
174 | #[repr(i32)]
| ^^^
error: `FromBytes` only supported on enums with `#[repr(...)]` attributes `u8`, `i8`, `u16`, or `i16`
--> tests/ui-stable/enum.rs:180:8
|
180 | #[repr(u64)]
| ^^^
error: `FromBytes` only supported on enums with `#[repr(...)]` attributes `u8`, `i8`, `u16`, or `i16`
--> tests/ui-stable/enum.rs:186:8
|
186 | #[repr(i64)]
| ^^^
error: must have #[repr(u8)] or #[repr(i8)] attribute in order to guarantee this type's alignment
--> tests/ui-stable/enum.rs:456:10
|
456 | #[derive(Unaligned)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)
error: must have #[repr(u8)] or #[repr(i8)] attribute in order to guarantee this type's alignment
--> tests/ui-stable/enum.rs:462:10
|
462 | #[derive(Unaligned)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)
error: must have #[repr(u8)] or #[repr(i8)] attribute in order to guarantee this type's alignment
--> tests/ui-stable/enum.rs:468:10
|
468 | #[derive(Unaligned)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)
error: must have #[repr(u8)] or #[repr(i8)] attribute in order to guarantee this type's alignment
--> tests/ui-stable/enum.rs:474:10
|
474 | #[derive(Unaligned)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)
error: must have #[repr(u8)] or #[repr(i8)] attribute in order to guarantee this type's alignment
--> tests/ui-stable/enum.rs:480:10
|
480 | #[derive(Unaligned)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)
error: must have #[repr(u8)] or #[repr(i8)] attribute in order to guarantee this type's alignment
--> tests/ui-stable/enum.rs:486:10
|
486 | #[derive(Unaligned)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)
error: must have #[repr(u8)] or #[repr(i8)] attribute in order to guarantee this type's alignment
--> tests/ui-stable/enum.rs:492:10
|
492 | #[derive(Unaligned)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)
error: must have #[repr(u8)] or #[repr(i8)] attribute in order to guarantee this type's alignment
--> tests/ui-stable/enum.rs:498:10
|
498 | #[derive(Unaligned)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)
error: must have #[repr(u8)] or #[repr(i8)] attribute in order to guarantee this type's alignment
--> tests/ui-stable/enum.rs:504:10
|
504 | #[derive(Unaligned)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)
error: cannot derive `Unaligned` on type with alignment greater than 1
--> tests/ui-stable/enum.rs:511:12
|
511 | #[repr(u8, align(2))]
| ^^^^^
error: cannot derive `Unaligned` on type with alignment greater than 1
--> tests/ui-stable/enum.rs:517:12
|
517 | #[repr(i8, align(2))]
| ^^^^^
error: this conflicts with another representation hint
--> tests/ui-stable/enum.rs:523:18
|
523 | #[repr(align(1), align(2))]
| ^^^^^
error: this conflicts with another representation hint
--> tests/ui-stable/enum.rs:529:18
|
529 | #[repr(align(2), align(4))]
| ^^^^^
error: must have #[repr(C)] or #[repr(Int)] attribute in order to guarantee this type's memory layout
--> tests/ui-stable/enum.rs:562:10
|
562 | #[derive(IntoBytes)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error: must have #[repr(C)] or #[repr(Int)] attribute in order to guarantee this type's memory layout
--> tests/ui-stable/enum.rs:568:10
|
568 | #[derive(IntoBytes)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error: generic parameters may not be used in const operations
--> tests/ui-stable/enum.rs:576:7
|
576 | A(T),
| ^ cannot perform const operation using `T`
|
= note: type parameters may not be used in const expressions
error[E0565]: meta item in `repr` must be an identifier
--> tests/ui-stable/enum.rs:19:1
|
19 | #[repr("foo")]
| ^^^^^^^^^^^^^^
error[E0552]: unrecognized representation hint
--> tests/ui-stable/enum.rs:25:8
|
25 | #[repr(foo)]
| ^^^
|
= help: valid reprs are `Rust` (default), `C`, `align`, `packed`, `transparent`, `simd`, `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize`
error[E0566]: conflicting representation hints
--> tests/ui-stable/enum.rs:37:8
|
37 | #[repr(u8, u16)]
| ^^ ^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #68585 <https://github.com/rust-lang/rust/issues/68585>
= note: `#[deny(conflicting_repr_hints)]` on by default
error[E0277]: the trait bound `UnsafeCell<()>: Immutable` is not satisfied
--> tests/ui-stable/enum.rs:51:10
|
51 | #[derive(Immutable)]
| ^^^^^^^^^ the trait `Immutable` is not implemented for `UnsafeCell<()>`
|
= note: Consider adding `#[derive(Immutable)]` to `UnsafeCell<()>`
= help: the following other types implement trait `Immutable`:
&T
&mut T
()
*const T
*mut T
F32<O>
F64<O>
I128<O>
and $N others
= help: see issue #48214
= note: this error originates in the derive macro `Immutable` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `UnsafeCell<u8>: Immutable` is not satisfied
--> tests/ui-stable/enum.rs:59:10
|
59 | #[derive(Immutable)]
| ^^^^^^^^^ the trait `Immutable` is not implemented for `UnsafeCell<u8>`
|
= note: Consider adding `#[derive(Immutable)]` to `UnsafeCell<u8>`
= help: the following other types implement trait `Immutable`:
&T
&mut T
()
*const T
*mut T
F32<O>
F64<O>
I128<O>
and $N others
= help: see issue #48214
= note: this error originates in the derive macro `Immutable` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `NotTryFromBytes: TryFromBytes` is not satisfied
--> tests/ui-stable/enum.rs:82:10
|
82 | #[derive(TryFromBytes)]
| ^^^^^^^^^^^^ the trait `TryFromBytes` is not implemented for `NotTryFromBytes`
|
= note: Consider adding `#[derive(TryFromBytes)]` to `NotTryFromBytes`
= help: the following other types implement trait `TryFromBytes`:
()
*const T
*mut T
<FromZeros6 as TryFromBytes>::is_bit_valid::___ZerocopyVariantStruct_A
<TryFromBytes3 as TryFromBytes>::is_bit_valid::___ZerocopyVariantStruct_A
AtomicBool
AtomicI16
AtomicI32
and $N others
= help: see issue #48214
= note: this error originates in the derive macro `TryFromBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `NotFromZeros: TryFromBytes` is not satisfied
--> tests/ui-stable/enum.rs:127:10
|
127 | #[derive(FromZeros)]
| ^^^^^^^^^ the trait `TryFromBytes` is not implemented for `NotFromZeros`
|
= note: Consider adding `#[derive(TryFromBytes)]` to `NotFromZeros`
= help: the following other types implement trait `TryFromBytes`:
()
*const T
*mut T
<FromZeros6 as TryFromBytes>::is_bit_valid::___ZerocopyVariantStruct_A
<TryFromBytes3 as TryFromBytes>::is_bit_valid::___ZerocopyVariantStruct_A
AtomicBool
AtomicI16
AtomicI32
and $N others
= help: see issue #48214
= note: this error originates in the derive macro `FromZeros` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `NotFromZeros: FromZeros` is not satisfied
--> tests/ui-stable/enum.rs:127:10
|
127 | #[derive(FromZeros)]
| ^^^^^^^^^ the trait `FromZeros` is not implemented for `NotFromZeros`
|
= note: Consider adding `#[derive(FromZeros)]` to `NotFromZeros`
= help: the following other types implement trait `FromZeros`:
()
*const T
*mut T
AtomicBool
AtomicI16
AtomicI32
AtomicI64
AtomicI8
and $N others
= help: see issue #48214
= note: this error originates in the derive macro `FromZeros` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `bool: FromBytes` is not satisfied
--> tests/ui-stable/enum.rs:191:10
|
191 | #[derive(FromBytes)]
| ^^^^^^^^^ the trait `FromBytes` is not implemented for `bool`
|
= note: Consider adding `#[derive(FromBytes)]` to `bool`
= help: the following other types implement trait `FromBytes`:
()
AtomicI16
AtomicI32
AtomicI64
AtomicI8
AtomicIsize
AtomicU16
AtomicU32
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]: `IntoBytes1` has 1 total byte(s) of padding
--> tests/ui-stable/enum.rs:538:10
|
538 | #[derive(IntoBytes)]
| ^^^^^^^^^ types with padding cannot implement `IntoBytes`
|
= note: consider using `zerocopy::Unalign` to lower the alignment of individual fields
= note: consider adding explicit fields where padding would be
= note: consider using `#[repr(packed)]` to remove padding
= help: the trait `PaddingFree<IntoBytes1, 1>` is not implemented for `()`
but trait `PaddingFree<IntoBytes1, 0>` is implemented for it
= help: see issue #48214
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: `IntoBytes2` has 3 total byte(s) of padding
--> tests/ui-stable/enum.rs:549:10
|
549 | #[derive(IntoBytes)]
| ^^^^^^^^^ types with padding cannot implement `IntoBytes`
|
= note: consider using `zerocopy::Unalign` to lower the alignment of individual fields
= note: consider adding explicit fields where padding would be
= note: consider using `#[repr(packed)]` to remove padding
= help: the trait `PaddingFree<IntoBytes2, 3>` is not implemented for `()`
but trait `PaddingFree<IntoBytes2, 0>` is implemented for it
= help: see issue #48214
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: `IntoBytes3` has 2 total byte(s) of padding
--> tests/ui-stable/enum.rs:555:10
|
555 | #[derive(IntoBytes)]
| ^^^^^^^^^ types with padding cannot implement `IntoBytes`
|
= note: consider using `zerocopy::Unalign` to lower the alignment of individual fields
= note: consider adding explicit fields where padding would be
= note: consider using `#[repr(packed)]` to remove padding
= help: the trait `PaddingFree<IntoBytes3, 2>` is not implemented for `()`
but trait `PaddingFree<IntoBytes3, 0>` is implemented for it
= help: see issue #48214
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error: generic `Self` types are currently not permitted in anonymous constants
--> tests/ui-stable/enum.rs:573:10
|
573 | #[derive(IntoBytes)]
| ^^^^^^^^^
|
note: not a concrete type
--> tests/ui-stable/enum.rs:573:10
|
573 | #[derive(IntoBytes)]
| ^^^^^^^^^
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `bool: FromBytes` is not satisfied
--> tests/ui-stable/enum.rs:191:10
|
191 | #[derive(FromBytes)]
| ^^^^^^^^^ the trait `FromBytes` is not implemented for `bool`
|
= note: Consider adding `#[derive(FromBytes)]` to `bool`
= help: the following other types implement trait `FromBytes`:
()
AtomicI16
AtomicI32
AtomicI64
AtomicI8
AtomicIsize
AtomicU16
AtomicU32
and $N others
note: required for `FooU8` to implement `FromBytes`
--> tests/ui-stable/enum.rs:191:10
|
191 | #[derive(FromBytes)]
| ^^^^^^^^^ unsatisfied trait bound introduced in this `derive` macro
note: required by a bound in `assert_is_from_bytes`
--> tests/ui-stable/enum.rs:191:10
|
191 | #[derive(FromBytes)]
| ^^^^^^^^^ required by this bound in `assert_is_from_bytes`
= note: this error originates in the derive macro `FromBytes` (in Nightly builds, run with -Z macro-backtrace for more info)

View File

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

View File

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

View File

@@ -0,0 +1,85 @@
// Copyright 2019 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.
#[macro_use]
extern crate zerocopy;
#[path = "../include.rs"]
mod util;
use zerocopy::KnownLayout;
use self::util::util::{NotZerocopy, AU16};
fn main() {}
// These tests cause errors which are generated by a later compilation pass than
// the other errors we generate, and so if they're compiled in the same file,
// the compiler will never get to that pass, and so we won't get the errors.
//
// TryFromBytes errors
//
#[derive(TryFromBytes)]
struct TryFromBytes1 {
value: NotZerocopy,
}
//
// FromZeros errors
//
#[derive(FromZeros)]
struct FromZeros1 {
value: NotZerocopy,
}
//
// FromBytes errors
//
#[derive(FromBytes)]
struct FromBytes1 {
value: NotZerocopy,
}
//
// IntoBytes errors
//
#[derive(IntoBytes)]
#[repr(C)]
struct IntoBytes1 {
value: NotZerocopy,
}
//
// Unaligned errors
//
#[derive(Unaligned)]
#[repr(C)]
struct Unaligned1 {
aligned: AU16,
}
// This specifically tests a bug we had in an old version of the code in which
// the trait bound would only be enforced for the first field's type.
#[derive(Unaligned)]
#[repr(C)]
struct Unaligned2 {
unaligned: u8,
aligned: AU16,
}
#[derive(Unaligned)]
#[repr(transparent)]
struct Unaligned3 {
aligned: AU16,
}

View File

@@ -0,0 +1,236 @@
warning: unused import: `zerocopy::KnownLayout`
--> tests/ui-stable/late_compile_pass.rs:15:5
|
15 | use zerocopy::KnownLayout;
| ^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(unused_imports)]` on by default
error[E0277]: the trait bound `NotZerocopy: zerocopy::TryFromBytes` is not satisfied
--> tests/ui-stable/late_compile_pass.rs:29:10
|
29 | #[derive(TryFromBytes)]
| ^^^^^^^^^^^^ the trait `zerocopy::TryFromBytes` is not implemented for `NotZerocopy`
|
= note: Consider adding `#[derive(TryFromBytes)]` to `NotZerocopy`
= help: the following other types implement trait `zerocopy::TryFromBytes`:
()
*const T
*mut T
AU16
AtomicBool
AtomicI16
AtomicI32
AtomicI64
and $N others
= help: see issue #48214
= note: this error originates in the derive macro `TryFromBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `NotZerocopy: zerocopy::TryFromBytes` is not satisfied
--> tests/ui-stable/late_compile_pass.rs:38:10
|
38 | #[derive(FromZeros)]
| ^^^^^^^^^ the trait `zerocopy::TryFromBytes` is not implemented for `NotZerocopy`
|
= note: Consider adding `#[derive(TryFromBytes)]` to `NotZerocopy`
= help: the following other types implement trait `zerocopy::TryFromBytes`:
()
*const T
*mut T
AU16
AtomicBool
AtomicI16
AtomicI32
AtomicI64
and $N others
= help: see issue #48214
= note: this error originates in the derive macro `FromZeros` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `NotZerocopy: FromZeros` is not satisfied
--> tests/ui-stable/late_compile_pass.rs:38:10
|
38 | #[derive(FromZeros)]
| ^^^^^^^^^ the trait `FromZeros` is not implemented for `NotZerocopy`
|
= note: Consider adding `#[derive(FromZeros)]` to `NotZerocopy`
= help: the following other types implement trait `FromZeros`:
()
*const T
*mut T
AU16
AtomicBool
AtomicI16
AtomicI32
AtomicI64
and $N others
= help: see issue #48214
= note: this error originates in the derive macro `FromZeros` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `NotZerocopy: zerocopy::TryFromBytes` is not satisfied
--> tests/ui-stable/late_compile_pass.rs:47:10
|
47 | #[derive(FromBytes)]
| ^^^^^^^^^ the trait `zerocopy::TryFromBytes` is not implemented for `NotZerocopy`
|
= note: Consider adding `#[derive(TryFromBytes)]` to `NotZerocopy`
= help: the following other types implement trait `zerocopy::TryFromBytes`:
()
*const T
*mut T
AU16
AtomicBool
AtomicI16
AtomicI32
AtomicI64
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 `NotZerocopy: FromZeros` is not satisfied
--> tests/ui-stable/late_compile_pass.rs:47:10
|
47 | #[derive(FromBytes)]
| ^^^^^^^^^ the trait `FromZeros` is not implemented for `NotZerocopy`
|
= note: Consider adding `#[derive(FromZeros)]` to `NotZerocopy`
= help: the following other types implement trait `FromZeros`:
()
*const T
*mut T
AU16
AtomicBool
AtomicI16
AtomicI32
AtomicI64
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 `NotZerocopy: zerocopy::FromBytes` is not satisfied
--> tests/ui-stable/late_compile_pass.rs:47:10
|
47 | #[derive(FromBytes)]
| ^^^^^^^^^ the trait `zerocopy::FromBytes` is not implemented for `NotZerocopy`
|
= note: Consider adding `#[derive(FromBytes)]` to `NotZerocopy`
= help: the following other types implement trait `zerocopy::FromBytes`:
()
AU16
AtomicI16
AtomicI32
AtomicI64
AtomicI8
AtomicIsize
AtomicU16
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 `NotZerocopy: zerocopy::IntoBytes` is not satisfied
--> tests/ui-stable/late_compile_pass.rs:56:10
|
56 | #[derive(IntoBytes)]
| ^^^^^^^^^ the trait `zerocopy::IntoBytes` is not implemented for `NotZerocopy`
|
= note: Consider adding `#[derive(IntoBytes)]` to `NotZerocopy`
= help: the following other types implement trait `zerocopy::IntoBytes`:
()
AU16
AtomicBool
AtomicI16
AtomicI32
AtomicI64
AtomicI8
AtomicIsize
and $N others
= help: see issue #48214
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `AU16: zerocopy::Unaligned` is not satisfied
--> tests/ui-stable/late_compile_pass.rs:66:10
|
66 | #[derive(Unaligned)]
| ^^^^^^^^^ the trait `zerocopy::Unaligned` is not implemented for `AU16`
|
= note: Consider adding `#[derive(Unaligned)]` to `AU16`
= help: the following other types implement trait `zerocopy::Unaligned`:
()
AtomicBool
AtomicI8
AtomicU8
Cell<T>
F32<O>
F64<O>
I128<O>
and $N others
= help: see issue #48214
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `AU16: zerocopy::Unaligned` is not satisfied
--> tests/ui-stable/late_compile_pass.rs:74:10
|
74 | #[derive(Unaligned)]
| ^^^^^^^^^ the trait `zerocopy::Unaligned` is not implemented for `AU16`
|
= note: Consider adding `#[derive(Unaligned)]` to `AU16`
= help: the following other types implement trait `zerocopy::Unaligned`:
()
AtomicBool
AtomicI8
AtomicU8
Cell<T>
F32<O>
F64<O>
I128<O>
and $N others
= help: see issue #48214
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `AU16: zerocopy::Unaligned` is not satisfied
--> tests/ui-stable/late_compile_pass.rs:81:10
|
81 | #[derive(Unaligned)]
| ^^^^^^^^^ the trait `zerocopy::Unaligned` is not implemented for `AU16`
|
= note: Consider adding `#[derive(Unaligned)]` to `AU16`
= help: the following other types implement trait `zerocopy::Unaligned`:
()
AtomicBool
AtomicI8
AtomicU8
Cell<T>
F32<O>
F64<O>
I128<O>
and $N others
= help: see issue #48214
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `NotZerocopy: zerocopy::FromBytes` is not satisfied
--> tests/ui-stable/late_compile_pass.rs:47:10
|
47 | #[derive(FromBytes)]
| ^^^^^^^^^ the trait `zerocopy::FromBytes` is not implemented for `NotZerocopy`
|
= note: Consider adding `#[derive(FromBytes)]` to `NotZerocopy`
= help: the following other types implement trait `zerocopy::FromBytes`:
()
AU16
AtomicI16
AtomicI32
AtomicI64
AtomicI8
AtomicIsize
AtomicU16
and $N others
note: required for `FromBytes1` to implement `zerocopy::FromBytes`
--> tests/ui-stable/late_compile_pass.rs:47:10
|
47 | #[derive(FromBytes)]
| ^^^^^^^^^ unsatisfied trait bound introduced in this `derive` macro
note: required by a bound in `<FromBytes1 as zerocopy::TryFromBytes>::is_bit_valid::assert_is_from_bytes`
--> tests/ui-stable/late_compile_pass.rs:47:10
|
47 | #[derive(FromBytes)]
| ^^^^^^^^^ required by this bound in `assert_is_from_bytes`
= note: this error originates in the derive macro `FromBytes` (in Nightly builds, run with -Z macro-backtrace for more info)

View File

@@ -0,0 +1,61 @@
// Copyright 2023 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.
extern crate zerocopy;
use zerocopy::KnownLayout;
fn main() {}
// These tests cause errors which are generated by a later compilation pass than
// the other errors we generate, and so if they're compiled in the same file,
// the compiler will never get to that pass, and so we won't get the errors.
//
// KnownLayout errors
//
fn assert_kl<T: ?Sized + KnownLayout>(_: &T) {}
// | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
// | N | Y | N | N | KL04 |
#[derive(KnownLayout)]
struct KL04<T: ?Sized>(u8, T);
fn test_kl04<T: ?Sized>(kl: &KL04<T>) {
assert_kl(kl);
}
// | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
// | N | Y | Y | N | KL06 |
#[derive(KnownLayout)]
struct KL06<T: ?Sized + KnownLayout>(u8, T);
fn test_kl06<T: ?Sized + KnownLayout>(kl: &KL06<T>) {
assert_kl(kl);
}
// | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
// | Y | Y | N | N | KL12 |
#[derive(KnownLayout)]
#[repr(C)]
struct KL12<T: ?Sized>(u8, T);
fn test_kl12<T: ?Sized>(kl: &KL12<T>) {
assert_kl(kl)
}
// | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
// | Y | Y | N | Y | KL13 |
#[derive(KnownLayout)]
#[repr(C)]
struct KL13<T>(u8, T);
fn test_kl13<T>(t: T) -> impl KnownLayout {
KL13(0u8, t)
}

View File

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

View File

@@ -0,0 +1,254 @@
// Copyright 2019 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.
#[macro_use]
extern crate zerocopy;
#[path = "../include.rs"]
mod util;
use zerocopy::{IntoBytes, KnownLayout};
use self::util::util::AU16;
fn main() {}
//
// KnownLayout errors
//
struct NotKnownLayout;
struct NotKnownLayoutDst([u8]);
// | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
// | N | N | N | N | KL00 |
#[derive(KnownLayout)]
struct KL00(u8, NotKnownLayoutDst);
// | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
// | N | N | Y | N | KL02 |
#[derive(KnownLayout)]
struct KL02(u8, [u8]);
// | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
// | Y | N | N | N | KL08 |
#[derive(KnownLayout)]
#[repr(C)]
struct KL08(u8, NotKnownLayoutDst);
// | `repr(C)`? | generic? | `KnownLayout`? | `Sized`? | Type Name |
// | Y | N | N | Y | KL09 |
#[derive(KnownLayout)]
#[repr(C)]
struct KL09(NotKnownLayout, NotKnownLayout);
//
// Immutable errors
//
#[derive(Immutable)]
struct Immutable1 {
a: core::cell::UnsafeCell<()>,
}
#[derive(Immutable)]
struct Immutable2 {
a: [core::cell::UnsafeCell<u8>; 0],
}
//
// TryFromBytes errors
//
#[derive(TryFromBytes)]
#[repr(packed)]
struct TryFromBytesPacked {
foo: AU16,
}
#[derive(TryFromBytes)]
#[repr(packed(1))]
struct TryFromBytesPackedN {
foo: AU16,
}
#[derive(TryFromBytes)]
#[repr(C, packed)]
struct TryFromBytesCPacked {
foo: AU16,
}
#[derive(TryFromBytes)]
#[repr(C, packed(1))]
struct TryFromBytesCPackedN {
foo: AU16,
}
//
// IntoBytes errors
//
// Since `IntoBytes1` has at least one generic parameter, an `IntoBytes` impl is
// emitted in which each field type is given an `Unaligned` bound. Since `foo`'s
// type doesn't implement `Unaligned`, this should fail.
#[derive(IntoBytes)]
#[repr(C)]
struct IntoBytes1<T> {
foo: AU16,
bar: T,
}
#[derive(IntoBytes)]
#[repr(C)]
struct IntoBytes2 {
foo: u8,
bar: AU16,
}
#[derive(IntoBytes)]
#[repr(C, packed(2))]
struct IntoBytes3 {
foo: u8,
// We'd prefer to use AU64 here, but you can't use aligned types in
// packed structs.
bar: u64,
}
type SliceU8 = [u8];
// Padding between `u8` and `SliceU8`. `SliceU8` doesn't syntactically look like
// a slice, so this case is handled by our `Sized` support.
//
// NOTE(#1708): This exists to ensure that our error messages are good when a
// field is unsized.
#[derive(IntoBytes)]
#[repr(C)]
struct IntoBytes4 {
a: u8,
b: SliceU8,
}
// Padding between `u8` and `[u16]`. `[u16]` is syntactically identifiable as a
// slice, so this case is handled by our `repr(C)` slice DST support.
#[derive(IntoBytes)]
#[repr(C)]
struct IntoBytes5 {
a: u8,
b: [u16],
}
// Trailing padding after `[u8]`. `[u8]` is syntactically identifiable as a
// slice, so this case is handled by our `repr(C)` slice DST support.
#[derive(IntoBytes)]
#[repr(C)]
struct IntoBytes6 {
a: u16,
b: [u8],
}
// Padding between `u8` and `u16` and also trailing padding after `[u8]`. `[u8]`
// is syntactically identifiable as a slice, so this case is handled by our
// `repr(C)` slice DST support.
#[derive(IntoBytes)]
#[repr(C)]
struct IntoBytes7 {
a: u8,
b: u16,
c: [u8],
}
#[derive(IntoBytes)]
#[repr(C, C)] // zerocopy-derive conservatively treats these as conflicting reprs
struct IntoBytes8 {
a: u8,
}
#[derive(IntoBytes)]
struct IntoBytes9<T> {
t: T,
}
#[derive(IntoBytes)]
#[repr(packed(2))]
struct IntoBytes10<T> {
t: T,
}
// `repr(C, packed(2))` is not equivalent to `repr(C, packed)`.
#[derive(IntoBytes)]
#[repr(C, packed(2))]
struct IntoBytes11<T> {
t0: T,
// Add a second field to avoid triggering the "repr(C) struct with one
// field" special case.
t1: T,
}
fn is_into_bytes_11<T: IntoBytes>() {
if false {
is_into_bytes_11::<IntoBytes11<AU16>>();
}
}
// `repr(C, align(2))` is not sufficient to guarantee the layout of this type.
#[derive(IntoBytes)]
#[repr(C, align(2))]
struct IntoBytes12<T> {
t: T,
}
//
// Unaligned errors
//
#[derive(Unaligned)]
#[repr(C, align(2))]
struct Unaligned1;
#[derive(Unaligned)]
#[repr(transparent, align(2))]
struct Unaligned2 {
foo: u8,
}
#[derive(Unaligned)]
#[repr(packed, align(2))]
struct Unaligned3;
#[derive(Unaligned)]
#[repr(align(1), align(2))]
struct Unaligned4;
#[derive(Unaligned)]
#[repr(align(2), align(4))]
struct Unaligned5;
#[derive(Unaligned)]
struct Unaligned6;
#[derive(Unaligned)]
#[repr(packed(2))]
struct Unaligned7;
// Test the error message emitted when conflicting reprs appear on different
// lines. On the nightly compiler, this emits a "joint span" that spans both
// problematic repr token trees and everything in between.
#[derive(Copy, Clone)]
#[repr(packed(2), C)]
#[derive(Unaligned)]
#[repr(C, packed(2))]
struct WeirdReprSpan;
#[derive(SplitAt)]
#[repr(C)]
struct SplitAtNotKnownLayout([u8]);
#[derive(SplitAt, KnownLayout)]
#[repr(C)]
struct SplitAtSized(u8);

View File

@@ -0,0 +1,445 @@
error: this conflicts with another representation hint
--> tests/ui-stable/struct.rs:167:11
|
167 | #[repr(C, C)] // zerocopy-derive conservatively treats these as conflicting reprs
| ^
error: must have a non-align #[repr(...)] attribute in order to guarantee this type's memory layout
--> tests/ui-stable/struct.rs:172:10
|
172 | #[derive(IntoBytes)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error: must have a non-align #[repr(...)] attribute in order to guarantee this type's memory layout
--> tests/ui-stable/struct.rs:177:10
|
177 | #[derive(IntoBytes)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error: must have a non-align #[repr(...)] attribute in order to guarantee this type's memory layout
--> tests/ui-stable/struct.rs:200:10
|
200 | #[derive(IntoBytes)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error: cannot derive `Unaligned` on type with alignment greater than 1
--> tests/ui-stable/struct.rs:211:11
|
211 | #[repr(C, align(2))]
| ^^^^^
error: this conflicts with another representation hint
--> tests/ui-stable/struct.rs:215:8
|
215 | #[repr(transparent, align(2))]
| ^^^^^^^^^^^
error: this conflicts with another representation hint
--> tests/ui-stable/struct.rs:221:16
|
221 | #[repr(packed, align(2))]
| ^^^^^
error: this conflicts with another representation hint
--> tests/ui-stable/struct.rs:225:18
|
225 | #[repr(align(1), align(2))]
| ^^^^^
error: this conflicts with another representation hint
--> tests/ui-stable/struct.rs:229:18
|
229 | #[repr(align(2), align(4))]
| ^^^^^
error: must have #[repr(C)], #[repr(transparent)], or #[repr(packed)] attribute in order to guarantee this type's alignment
--> tests/ui-stable/struct.rs:232:10
|
232 | #[derive(Unaligned)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)
error: must have #[repr(C)], #[repr(transparent)], or #[repr(packed)] attribute in order to guarantee this type's alignment
--> tests/ui-stable/struct.rs:235:10
|
235 | #[derive(Unaligned)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)
error: this conflicts with another representation hint
--> tests/ui-stable/struct.rs:245:8
|
245 | #[repr(C, packed(2))]
| ^
error[E0692]: transparent struct cannot have other repr hints
--> tests/ui-stable/struct.rs:215:8
|
215 | #[repr(transparent, align(2))]
| ^^^^^^^^^^^ ^^^^^^^^
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
--> tests/ui-stable/struct.rs:31:10
|
31 | #[derive(KnownLayout)]
| ^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: within `KL00`, the trait `Sized` is not implemented for `[u8]`
note: required because it appears within the type `KL00`
--> tests/ui-stable/struct.rs:32:8
|
32 | struct KL00(u8, NotKnownLayoutDst);
| ^^^^
= help: see issue #48214
= note: this error originates in the derive macro `KnownLayout` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
--> tests/ui-stable/struct.rs:36:10
|
36 | #[derive(KnownLayout)]
| ^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: within `KL02`, the trait `Sized` is not implemented for `[u8]`
note: required because it appears within the type `KL02`
--> tests/ui-stable/struct.rs:37:8
|
37 | struct KL02(u8, [u8]);
| ^^^^
= help: see issue #48214
= note: this error originates in the derive macro `KnownLayout` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `NotKnownLayoutDst: zerocopy::KnownLayout` is not satisfied
--> tests/ui-stable/struct.rs:41:10
|
41 | #[derive(KnownLayout)]
| ^^^^^^^^^^^ the trait `zerocopy::KnownLayout` is not implemented for `NotKnownLayoutDst`
|
= note: Consider adding `#[derive(KnownLayout)]` to `NotKnownLayoutDst`
= help: the following other types implement trait `zerocopy::KnownLayout`:
&T
&mut T
()
*const T
*mut T
AU16
AtomicBool
AtomicI16
and $N others
= help: see issue #48214
= note: this error originates in the derive macro `KnownLayout` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `NotKnownLayout: zerocopy::KnownLayout` is not satisfied
--> tests/ui-stable/struct.rs:47:10
|
47 | #[derive(KnownLayout)]
| ^^^^^^^^^^^ the trait `zerocopy::KnownLayout` is not implemented for `NotKnownLayout`
|
= note: Consider adding `#[derive(KnownLayout)]` to `NotKnownLayout`
= help: the following other types implement trait `zerocopy::KnownLayout`:
&T
&mut T
()
*const T
*mut T
AU16
AtomicBool
AtomicI16
and $N others
= help: see issue #48214
= note: this error originates in the derive macro `KnownLayout` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `UnsafeCell<()>: zerocopy::Immutable` is not satisfied
--> tests/ui-stable/struct.rs:55:10
|
55 | #[derive(Immutable)]
| ^^^^^^^^^ the trait `zerocopy::Immutable` is not implemented for `UnsafeCell<()>`
|
= note: Consider adding `#[derive(Immutable)]` to `UnsafeCell<()>`
= help: the following other types implement trait `zerocopy::Immutable`:
&T
&mut T
()
*const T
*mut T
AU16
F32<O>
F64<O>
and $N others
= help: see issue #48214
= note: this error originates in the derive macro `Immutable` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `UnsafeCell<u8>: zerocopy::Immutable` is not satisfied
--> tests/ui-stable/struct.rs:60:10
|
60 | #[derive(Immutable)]
| ^^^^^^^^^ the trait `zerocopy::Immutable` is not implemented for `UnsafeCell<u8>`
|
= note: Consider adding `#[derive(Immutable)]` to `UnsafeCell<u8>`
= help: the following other types implement trait `zerocopy::Immutable`:
&T
&mut T
()
*const T
*mut T
AU16
F32<O>
F64<O>
and $N others
= note: required for `[UnsafeCell<u8>; 0]` to implement `zerocopy::Immutable`
= help: see issue #48214
= note: this error originates in the derive macro `Immutable` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0588]: packed type cannot transitively contain a `#[repr(align)]` type
--> tests/ui-stable/struct.rs:71:1
|
71 | struct TryFromBytesPacked {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: `AU16` has a `#[repr(align)]` attribute
--> tests/ui-stable/../include.rs
|
| pub struct AU16(pub u16);
| ^^^^^^^^^^^^^^^
error[E0588]: packed type cannot transitively contain a `#[repr(align)]` type
--> tests/ui-stable/struct.rs:77:1
|
77 | struct TryFromBytesPackedN {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: `AU16` has a `#[repr(align)]` attribute
--> tests/ui-stable/../include.rs
|
| pub struct AU16(pub u16);
| ^^^^^^^^^^^^^^^
error[E0588]: packed type cannot transitively contain a `#[repr(align)]` type
--> tests/ui-stable/struct.rs:83:1
|
83 | struct TryFromBytesCPacked {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: `AU16` has a `#[repr(align)]` attribute
--> tests/ui-stable/../include.rs
|
| pub struct AU16(pub u16);
| ^^^^^^^^^^^^^^^
error[E0588]: packed type cannot transitively contain a `#[repr(align)]` type
--> tests/ui-stable/struct.rs:89:1
|
89 | struct TryFromBytesCPackedN {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: `AU16` has a `#[repr(align)]` attribute
--> tests/ui-stable/../include.rs
|
| pub struct AU16(pub u16);
| ^^^^^^^^^^^^^^^
error[E0277]: the trait bound `AU16: zerocopy::Unaligned` is not satisfied
--> tests/ui-stable/struct.rs:100:10
|
100 | #[derive(IntoBytes)]
| ^^^^^^^^^ the trait `zerocopy::Unaligned` is not implemented for `AU16`
|
= note: Consider adding `#[derive(Unaligned)]` to `AU16`
= help: the following other types implement trait `zerocopy::Unaligned`:
()
AtomicBool
AtomicI8
AtomicU8
Cell<T>
F32<O>
F64<O>
I128<O>
and $N others
= help: see issue #48214
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: `IntoBytes2` has 1 total byte(s) of padding
--> tests/ui-stable/struct.rs:107:10
|
107 | #[derive(IntoBytes)]
| ^^^^^^^^^ types with padding cannot implement `IntoBytes`
|
= note: consider using `zerocopy::Unalign` to lower the alignment of individual fields
= note: consider adding explicit fields where padding would be
= note: consider using `#[repr(packed)]` to remove padding
= help: the trait `PaddingFree<IntoBytes2, 1>` is not implemented for `()`
but trait `PaddingFree<IntoBytes2, 0>` is implemented for it
= help: see issue #48214
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: `IntoBytes3` has 1 total byte(s) of padding
--> tests/ui-stable/struct.rs:114:10
|
114 | #[derive(IntoBytes)]
| ^^^^^^^^^ types with padding cannot implement `IntoBytes`
|
= note: consider using `zerocopy::Unalign` to lower the alignment of individual fields
= note: consider adding explicit fields where padding would be
= note: consider using `#[repr(packed)]` to remove padding
= help: the trait `PaddingFree<IntoBytes3, 1>` is not implemented for `()`
but trait `PaddingFree<IntoBytes3, 0>` is implemented for it
= help: see issue #48214
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
--> tests/ui-stable/struct.rs:130:10
|
130 | #[derive(IntoBytes)]
| ^^^^^^^^^ doesn't have a size known at compile-time
|
= help: within `IntoBytes4`, the trait `Sized` is not implemented for `[u8]`
note: required because it appears within the type `IntoBytes4`
--> tests/ui-stable/struct.rs:132:8
|
132 | struct IntoBytes4 {
| ^^^^^^^^^^
= note: required for `IntoBytes4` to implement `macro_util::__size_of::Sized`
note: required by a bound in `macro_util::__size_of::size_of`
--> $WORKSPACE/src/util/macro_util.rs
|
| pub const fn size_of<T: Sized + ?core::marker::Sized>() -> usize {
| ^^^^^ required by this bound in `size_of`
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: `[u8]` is unsized
--> tests/ui-stable/struct.rs:134:8
|
134 | b: SliceU8,
| ^^^^^^^ `IntoBytes` needs all field types to be `Sized` in order to determine whether there is padding
|
= help: the trait `Sized` is not implemented for `[u8]`
= note: consider using `#[repr(packed)]` to remove padding
= note: `IntoBytes` does not require the fields of `#[repr(packed)]` types to be `Sized`
= note: required for `[u8]` to implement `macro_util::__size_of::Sized`
note: required by a bound in `macro_util::__size_of::size_of`
--> $WORKSPACE/src/util/macro_util.rs
|
| pub const fn size_of<T: Sized + ?core::marker::Sized>() -> usize {
| ^^^^^ required by this bound in `size_of`
error[E0277]: `IntoBytes5` has one or more padding bytes
--> tests/ui-stable/struct.rs:139:10
|
139 | #[derive(IntoBytes)]
| ^^^^^^^^^ types with padding cannot implement `IntoBytes`
|
= note: consider using `zerocopy::Unalign` to lower the alignment of individual fields
= note: consider adding explicit fields where padding would be
= note: consider using `#[repr(packed)]` to remove padding
= help: the trait `DynamicPaddingFree<IntoBytes5, true>` is not implemented for `()`
but trait `DynamicPaddingFree<IntoBytes5, false>` is implemented for it
= help: see issue #48214
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: `IntoBytes6` has one or more padding bytes
--> tests/ui-stable/struct.rs:148:10
|
148 | #[derive(IntoBytes)]
| ^^^^^^^^^ types with padding cannot implement `IntoBytes`
|
= note: consider using `zerocopy::Unalign` to lower the alignment of individual fields
= note: consider adding explicit fields where padding would be
= note: consider using `#[repr(packed)]` to remove padding
= help: the trait `DynamicPaddingFree<IntoBytes6, true>` is not implemented for `()`
but trait `DynamicPaddingFree<IntoBytes6, false>` is implemented for it
= help: see issue #48214
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: `IntoBytes7` has one or more padding bytes
--> tests/ui-stable/struct.rs:158:10
|
158 | #[derive(IntoBytes)]
| ^^^^^^^^^ types with padding cannot implement `IntoBytes`
|
= note: consider using `zerocopy::Unalign` to lower the alignment of individual fields
= note: consider adding explicit fields where padding would be
= note: consider using `#[repr(packed)]` to remove padding
= help: the trait `DynamicPaddingFree<IntoBytes7, true>` is not implemented for `()`
but trait `DynamicPaddingFree<IntoBytes7, false>` is implemented for it
= help: see issue #48214
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0587]: type has conflicting packed and align representation hints
--> tests/ui-stable/struct.rs:222:1
|
222 | struct Unaligned3;
| ^^^^^^^^^^^^^^^^^
error[E0277]: the trait bound `SplitAtNotKnownLayout: zerocopy::KnownLayout` is not satisfied
--> tests/ui-stable/struct.rs:248:10
|
248 | #[derive(SplitAt)]
| ^^^^^^^ the trait `zerocopy::KnownLayout` is not implemented for `SplitAtNotKnownLayout`
|
= note: Consider adding `#[derive(KnownLayout)]` to `SplitAtNotKnownLayout`
= help: the following other types implement trait `zerocopy::KnownLayout`:
&T
&mut T
()
*const T
*mut T
AU16
AtomicBool
AtomicI16
and $N others
note: required by a bound in `SplitAt`
--> $WORKSPACE/src/split_at.rs
|
| pub unsafe trait SplitAt: KnownLayout<PointerMetadata = usize> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `SplitAt`
= note: this error originates in the derive macro `SplitAt` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `u8: SplitAt` is not satisfied
--> tests/ui-stable/struct.rs:252:10
|
252 | #[derive(SplitAt, KnownLayout)]
| ^^^^^^^ the trait `SplitAt` is not implemented for `u8`
|
= note: Consider adding `#[derive(SplitAt)]` to `u8`
= help: the following other types implement trait `SplitAt`:
SplitAtNotKnownLayout
SplitAtSized
[T]
= help: see issue #48214
= note: this error originates in the derive macro `SplitAt` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `AU16: zerocopy::Unaligned` is not satisfied
--> tests/ui-stable/struct.rs:195:28
|
195 | is_into_bytes_11::<IntoBytes11<AU16>>();
| ^^^^^^^^^^^^^^^^^ the trait `zerocopy::Unaligned` is not implemented for `AU16`
|
= note: Consider adding `#[derive(Unaligned)]` to `AU16`
= help: the following other types implement trait `zerocopy::Unaligned`:
()
AtomicBool
AtomicI8
AtomicU8
Cell<T>
F32<O>
F64<O>
I128<O>
and $N others
note: required for `IntoBytes11<AU16>` to implement `zerocopy::IntoBytes`
--> tests/ui-stable/struct.rs:184:10
|
184 | #[derive(IntoBytes)]
| ^^^^^^^^^ unsatisfied trait bound introduced in this `derive` macro
note: required by a bound in `is_into_bytes_11`
--> tests/ui-stable/struct.rs:193:24
|
193 | fn is_into_bytes_11<T: IntoBytes>() {
| ^^^^^^^^^ required by this bound in `is_into_bytes_11`
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)

View File

@@ -0,0 +1,109 @@
// Copyright 2019 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.
#[macro_use]
extern crate zerocopy;
#[path = "../include.rs"]
mod util;
use std::mem::ManuallyDrop;
use self::util::util::AU16;
fn main() {}
//
// Immutable errors
//
#[derive(Immutable)]
union Immutable1 {
a: ManuallyDrop<core::cell::UnsafeCell<()>>,
}
//
// IntoBytes errors
//
#[derive(IntoBytes)]
#[repr(C)]
union IntoBytes1<T> {
foo: ManuallyDrop<T>,
}
#[derive(IntoBytes)]
#[repr(C)]
union IntoBytes2 {
foo: u8,
bar: [u8; 2],
}
// Need a `repr` attribute
#[derive(IntoBytes)]
union IntoBytes3 {
foo: u8,
}
// `repr(packed(2))` isn't equivalent to `repr(packed)`
#[derive(IntoBytes)]
#[repr(packed(2))]
union IntoBytes4 {
foo: u8,
}
//
// Unaligned errors
//
#[derive(Unaligned)]
#[repr(C, align(2))]
union Unaligned1 {
foo: i16,
bar: AU16,
}
// Transparent unions are unstable; see issue #60405
// <https://github.com/rust-lang/rust/issues/60405> for more information.
// #[derive(Unaligned)]
// #[repr(transparent, align(2))]
// union Unaligned2 {
// foo: u8,
// }
#[derive(Unaligned)]
#[repr(packed, align(2))]
union Unaligned3 {
foo: u8,
}
#[derive(Unaligned)]
#[repr(align(1), align(2))]
struct Unaligned4 {
foo: u8,
}
#[derive(Unaligned)]
#[repr(align(2), align(4))]
struct Unaligned5 {
foo: u8,
}
#[derive(Unaligned)]
union Unaligned6 {
foo: i16,
bar: AU16,
}
#[derive(Unaligned)]
#[repr(packed(2))]
union Unaligned7 {
foo: i16,
bar: AU16,
}

View File

@@ -0,0 +1,130 @@
error: unsupported on types with type parameters
--> tests/ui-stable/union.rs:34:10
|
34 | #[derive(IntoBytes)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error: must be #[repr(C)], #[repr(packed)], or #[repr(transparent)]
--> tests/ui-stable/union.rs:48:10
|
48 | #[derive(IntoBytes)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error: must be #[repr(C)], #[repr(packed)], or #[repr(transparent)]
--> tests/ui-stable/union.rs:54:10
|
54 | #[derive(IntoBytes)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error: cannot derive `Unaligned` on type with alignment greater than 1
--> tests/ui-stable/union.rs:65:11
|
65 | #[repr(C, align(2))]
| ^^^^^
error: this conflicts with another representation hint
--> tests/ui-stable/union.rs:81:16
|
81 | #[repr(packed, align(2))]
| ^^^^^
error: this conflicts with another representation hint
--> tests/ui-stable/union.rs:87:18
|
87 | #[repr(align(1), align(2))]
| ^^^^^
error: this conflicts with another representation hint
--> tests/ui-stable/union.rs:93:18
|
93 | #[repr(align(2), align(4))]
| ^^^^^
error: must have #[repr(C)], #[repr(transparent)], or #[repr(packed)] attribute in order to guarantee this type's alignment
--> tests/ui-stable/union.rs:98:10
|
98 | #[derive(Unaligned)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)
error: must have #[repr(C)], #[repr(transparent)], or #[repr(packed)] attribute in order to guarantee this type's alignment
--> tests/ui-stable/union.rs:104:10
|
104 | #[derive(Unaligned)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `Unaligned` (in Nightly builds, run with -Z macro-backtrace for more info)
warning: unexpected `cfg` condition name: `zerocopy_derive_union_into_bytes`
--> tests/ui-stable/union.rs:40:10
|
40 | #[derive(IntoBytes)]
| ^^^^^^^^^
|
= help: expected names are: `docsrs`, `feature`, and `test` and 31 more
= note: using a cfg inside a derive macro will use the cfgs from the destination crate and not the ones from the defining crate
= help: try referring to `IntoBytes` crate for guidance on how handle this unexpected cfg
= help: the derive macro `IntoBytes` may come from an old version of the `zerocopy_derive` crate, try updating your dependency with `cargo update -p zerocopy_derive`
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg/cargo-specifics.html> for more information about checking conditional configuration
= note: `#[warn(unexpected_cfgs)]` on by default
= note: this warning originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `UnsafeCell<()>: zerocopy::Immutable` is not satisfied
--> tests/ui-stable/union.rs:25:10
|
25 | #[derive(Immutable)]
| ^^^^^^^^^ the trait `zerocopy::Immutable` is not implemented for `UnsafeCell<()>`
|
= note: Consider adding `#[derive(Immutable)]` to `UnsafeCell<()>`
= help: the following other types implement trait `zerocopy::Immutable`:
&T
&mut T
()
*const T
*mut T
AU16
F32<O>
F64<O>
and $N others
= note: required for `ManuallyDrop<UnsafeCell<()>>` to implement `zerocopy::Immutable`
= help: see issue #48214
= note: this error originates in the derive macro `Immutable` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: `IntoBytes2` has 1 total byte(s) of padding
--> tests/ui-stable/union.rs:40:10
|
40 | #[derive(IntoBytes)]
| ^^^^^^^^^ types with padding cannot implement `IntoBytes`
|
= note: consider using `zerocopy::Unalign` to lower the alignment of individual fields
= note: consider adding explicit fields where padding would be
= note: consider using `#[repr(packed)]` to remove padding
= help: the trait `PaddingFree<IntoBytes2, 1>` is not implemented for `()`
but trait `PaddingFree<IntoBytes2, 0>` is implemented for it
= help: see issue #48214
= note: this error originates in the derive macro `IntoBytes` (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:82:1
|
82 | union Unaligned3 {
| ^^^^^^^^^^^^^^^^
error[E0588]: packed type cannot transitively contain a `#[repr(align)]` type
--> tests/ui-stable/union.rs:106:1
|
106 | union Unaligned7 {
| ^^^^^^^^^^^^^^^^
|
note: `AU16` has a `#[repr(align)]` attribute
--> tests/ui-stable/../include.rs
|
| pub struct AU16(pub u16);
| ^^^^^^^^^^^^^^^

View File

@@ -0,0 +1,26 @@
// Copyright 2024 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.
//! See: https://github.com/google/zerocopy/issues/553
//! zerocopy must still allow derives of deprecated types.
//! This test has a hand-written impl of a deprecated type, and should result in a compilation
//! error. If zerocopy does not tack an allow(deprecated) annotation onto its impls, then this
//! test will fail because more than one compile error will be generated.
#![deny(deprecated)]
extern crate zerocopy;
use zerocopy::IntoBytes;
#[derive(IntoBytes)]
#[repr(C)]
union Foo {
a: u8,
}
fn main() {}

View File

@@ -0,0 +1,22 @@
error: requires --cfg zerocopy_derive_union_into_bytes;
please let us know you use this feature: https://github.com/google/zerocopy/discussions/1802
--> tests/ui-stable/union_into_bytes_cfg/union_into_bytes_cfg.rs:20:10
|
20 | #[derive(IntoBytes)]
| ^^^^^^^^^
|
= note: this error originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)
warning: unexpected `cfg` condition name: `zerocopy_derive_union_into_bytes`
--> tests/ui-stable/union_into_bytes_cfg/union_into_bytes_cfg.rs:20:10
|
20 | #[derive(IntoBytes)]
| ^^^^^^^^^
|
= help: expected names are: `docsrs`, `feature`, and `test` and 31 more
= note: using a cfg inside a derive macro will use the cfgs from the destination crate and not the ones from the defining crate
= help: try referring to `IntoBytes` crate for guidance on how handle this unexpected cfg
= help: the derive macro `IntoBytes` may come from an old version of the `zerocopy_derive` crate, try updating your dependency with `cargo update -p zerocopy_derive`
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg/cargo-specifics.html> for more information about checking conditional configuration
= note: `#[warn(unexpected_cfgs)]` on by default
= note: this warning originates in the derive macro `IntoBytes` (in Nightly builds, run with -Z macro-backtrace for more info)

View File

@@ -0,0 +1,74 @@
// Copyright 2019 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.
// See comment in `include.rs` for why we disable the prelude.
#![no_implicit_prelude]
#![allow(warnings)]
include!("include.rs");
// A union is `imp::FromBytes` if:
// - all fields are `imp::FromBytes`
#[derive(Clone, Copy, imp::Immutable, imp::FromBytes)]
union Zst {
a: (),
}
util_assert_impl_all!(Zst: imp::FromBytes);
test_trivial_is_bit_valid!(Zst => test_zst_trivial_is_bit_valid);
#[derive(imp::Immutable, imp::FromBytes)]
union One {
a: u8,
}
util_assert_impl_all!(One: imp::FromBytes);
test_trivial_is_bit_valid!(One => test_one_trivial_is_bit_valid);
#[derive(imp::Immutable, imp::FromBytes)]
union Two {
a: u8,
b: Zst,
}
util_assert_impl_all!(Two: imp::FromBytes);
test_trivial_is_bit_valid!(Two => test_two_trivial_is_bit_valid);
#[derive(imp::Immutable, imp::FromBytes)]
union TypeParams<'a, T: imp::Copy, I: imp::Iterator>
where
I::Item: imp::Copy,
{
a: T,
c: I::Item,
d: u8,
e: imp::PhantomData<&'a [u8]>,
f: imp::PhantomData<&'static str>,
g: imp::PhantomData<imp::String>,
}
util_assert_impl_all!(TypeParams<'static, (), imp::IntoIter<()>>: imp::FromBytes);
test_trivial_is_bit_valid!(TypeParams<'static, (), imp::IntoIter<()>> => test_type_params_trivial_is_bit_valid);
// Deriving `imp::FromBytes` should work if the union has bounded parameters.
#[derive(imp::Immutable, imp::FromBytes)]
#[repr(C)]
union WithParams<'a: 'b, 'b: 'a, T: 'a + 'b + imp::FromBytes, const N: usize>
where
'a: 'b,
'b: 'a,
T: 'a + 'b + imp::Copy + imp::FromBytes,
{
a: [T; N],
b: imp::PhantomData<&'a &'b ()>,
}
util_assert_impl_all!(WithParams<'static, 'static, u8, 42>: imp::FromBytes);
test_trivial_is_bit_valid!(WithParams<'static, 'static, u8, 42> => test_with_params_trivial_is_bit_valid);

View File

@@ -0,0 +1,69 @@
// Copyright 2019 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.
// See comment in `include.rs` for why we disable the prelude.
#![no_implicit_prelude]
#![allow(warnings)]
include!("include.rs");
// A union is `imp::FromZeros` if:
// - all fields are `imp::FromZeros`
#[derive(Clone, Copy, imp::Immutable, imp::FromZeros)]
union Zst {
a: (),
}
util_assert_impl_all!(Zst: imp::FromZeros);
#[derive(imp::Immutable, imp::FromZeros)]
union One {
a: bool,
}
util_assert_impl_all!(One: imp::FromZeros);
#[derive(imp::Immutable, imp::FromZeros)]
union Two {
a: bool,
b: Zst,
}
util_assert_impl_all!(Two: imp::FromZeros);
#[derive(imp::Immutable, imp::FromZeros)]
union TypeParams<'a, T: imp::Copy, I: imp::Iterator>
where
I::Item: imp::Copy,
{
a: T,
c: I::Item,
d: u8,
e: imp::PhantomData<&'a [u8]>,
f: imp::PhantomData<&'static str>,
g: imp::PhantomData<imp::String>,
}
util_assert_impl_all!(TypeParams<'static, (), imp::IntoIter<()>>: imp::FromZeros);
// Deriving `imp::FromZeros` should work if the union has bounded parameters.
#[derive(imp::Immutable, imp::FromZeros)]
#[repr(C)]
union WithParams<'a: 'b, 'b: 'a, T: 'a + 'b + imp::FromZeros, const N: usize>
where
'a: 'b,
'b: 'a,
T: 'a + 'b + imp::Copy + imp::FromZeros,
{
a: [T; N],
b: imp::PhantomData<&'a &'b ()>,
}
util_assert_impl_all!(WithParams<'static, 'static, u8, 42>: imp::FromZeros);

View File

@@ -0,0 +1,66 @@
// Copyright 2023 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.
// See comment in `include.rs` for why we disable the prelude.
#![no_implicit_prelude]
#![allow(warnings)]
include!("include.rs");
#[derive(Clone, Copy, imp::KnownLayout)]
union Zst {
a: (),
}
util_assert_impl_all!(Zst: imp::KnownLayout);
#[derive(imp::KnownLayout)]
union One {
a: bool,
}
util_assert_impl_all!(One: imp::KnownLayout);
#[derive(imp::KnownLayout)]
union Two {
a: bool,
b: Zst,
}
util_assert_impl_all!(Two: imp::KnownLayout);
#[derive(imp::KnownLayout)]
union TypeParams<'a, T: imp::Copy, I: imp::Iterator>
where
I::Item: imp::Copy,
{
a: T,
c: I::Item,
d: u8,
e: imp::PhantomData<&'a [u8]>,
f: imp::PhantomData<&'static str>,
g: imp::PhantomData<imp::String>,
}
util_assert_impl_all!(TypeParams<'static, (), imp::IntoIter<()>>: imp::KnownLayout);
// Deriving `imp::KnownLayout` should work if the union has bounded parameters.
#[derive(imp::KnownLayout)]
#[repr(C)]
union WithParams<'a: 'b, 'b: 'a, T: 'a + 'b + imp::KnownLayout, const N: usize>
where
'a: 'b,
'b: 'a,
T: 'a + 'b + imp::Copy + imp::KnownLayout,
{
a: [T; N],
b: imp::PhantomData<&'a &'b ()>,
}
util_assert_impl_all!(WithParams<'static, 'static, u8, 42>: imp::KnownLayout);

View File

@@ -0,0 +1,68 @@
// Copyright 2023 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.
// See comment in `include.rs` for why we disable the prelude.
#![no_implicit_prelude]
#![allow(warnings)]
include!("include.rs");
#[derive(Clone, Copy, imp::Immutable)]
union Zst {
a: (),
}
util_assert_impl_all!(Zst: imp::Immutable);
#[derive(imp::Immutable)]
union One {
a: bool,
}
util_assert_impl_all!(One: imp::Immutable);
#[derive(imp::Immutable)]
union Two {
a: bool,
b: Zst,
}
util_assert_impl_all!(Two: imp::Immutable);
#[derive(imp::Immutable)]
union TypeParams<'a, T: imp::Copy, I: imp::Iterator>
where
I::Item: imp::Copy,
{
a: T,
c: I::Item,
d: u8,
e: imp::PhantomData<&'a [::core::primitive::u8]>,
f: imp::PhantomData<&'static ::core::primitive::str>,
g: imp::PhantomData<imp::String>,
}
util_assert_impl_all!(TypeParams<'static, (), imp::IntoIter<()>>: imp::Immutable);
// Deriving `imp::Immutable` should work if the union has bounded parameters.
#[derive(imp::Immutable)]
#[repr(C)]
union WithParams<'a: 'b, 'b: 'a, T: 'a + 'b + imp::Immutable, const N: usize>
where
'a: 'b,
'b: 'a,
T: 'a + 'b + imp::Copy + imp::Immutable,
{
a: [T; N],
b: imp::PhantomData<&'a &'b ()>,
c: imp::PhantomData<imp::UnsafeCell<()>>,
d: &'a imp::UnsafeCell<()>,
}
util_assert_impl_all!(WithParams<'static, 'static, u8, 42>: imp::Immutable);

View File

@@ -0,0 +1,75 @@
// Copyright 2019 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.
// See comment in `include.rs` for why we disable the prelude.
#![no_implicit_prelude]
#![allow(warnings)]
include!("include.rs");
// A union is `imp::IntoBytes` if:
// - all fields are `imp::IntoBytes`
// - `repr(C)` or `repr(transparent)` and
// - no padding (size of union equals size of each field type)
// - `repr(packed)`
#[derive(imp::IntoBytes, Clone, Copy)]
#[repr(C)]
union CZst {
a: (),
}
util_assert_impl_all!(CZst: imp::IntoBytes);
#[derive(imp::IntoBytes)]
#[repr(C)]
union C {
a: u8,
b: u8,
}
util_assert_impl_all!(C: imp::IntoBytes);
// Transparent unions are unstable; see issue #60405
// <https://github.com/rust-lang/rust/issues/60405> for more information.
// #[derive(imp::IntoBytes)]
// #[repr(transparent)]
// union Transparent {
// a: u8,
// b: CZst,
// }
// is_as_bytes!(Transparent);
#[derive(imp::IntoBytes)]
#[repr(C, packed)]
union CZstPacked {
a: (),
}
util_assert_impl_all!(CZstPacked: imp::IntoBytes);
#[derive(imp::IntoBytes)]
#[repr(C, packed)]
union CPacked {
a: u8,
b: i8,
}
util_assert_impl_all!(CPacked: imp::IntoBytes);
#[derive(imp::IntoBytes)]
#[repr(C, packed)]
union CMultibytePacked {
a: i32,
b: u32,
c: f32,
}
util_assert_impl_all!(CMultibytePacked: imp::IntoBytes);

View File

@@ -0,0 +1,183 @@
// Copyright 2023 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.
// See comment in `include.rs` for why we disable the prelude.
#![no_implicit_prelude]
#![allow(warnings)]
include!("include.rs");
// A struct is `imp::TryFromBytes` if:
// - any of its fields are `imp::TryFromBytes`
#[derive(imp::Immutable, imp::TryFromBytes)]
union One {
a: u8,
}
util_assert_impl_all!(One: imp::TryFromBytes);
#[test]
fn one() {
// FIXME(#5): Use `try_transmute` in this test once it's available.
let candidate = ::zerocopy::Ptr::from_ref(&One { a: 42 });
let candidate = candidate.forget_aligned();
// SAFETY: `&One` consists entirely of initialized bytes.
let candidate = unsafe { candidate.assume_initialized() };
let is_bit_valid = <One as imp::TryFromBytes>::is_bit_valid(candidate);
assert!(is_bit_valid);
}
#[derive(imp::Immutable, imp::TryFromBytes)]
#[repr(C)]
union Two {
a: bool,
b: bool,
}
util_assert_impl_all!(Two: imp::TryFromBytes);
#[test]
fn two() {
// FIXME(#5): Use `try_transmute` in this test once it's available.
let candidate_a = ::zerocopy::Ptr::from_ref(&Two { a: false });
let candidate_a = candidate_a.forget_aligned();
// SAFETY: `&Two` consists entirely of initialized bytes.
let candidate_a = unsafe { candidate_a.assume_initialized() };
let is_bit_valid = <Two as imp::TryFromBytes>::is_bit_valid(candidate_a);
assert!(is_bit_valid);
let candidate_b = ::zerocopy::Ptr::from_ref(&Two { b: true });
let candidate_b = candidate_b.forget_aligned();
// SAFETY: `&Two` consists entirely of initialized bytes.
let candidate_b = unsafe { candidate_b.assume_initialized() };
let is_bit_valid = <Two as imp::TryFromBytes>::is_bit_valid(candidate_b);
assert!(is_bit_valid);
}
#[test]
fn two_bad() {
// FIXME(#5): Use `try_transmute` in this test once it's available.
let candidate = ::zerocopy::Ptr::from_ref(&[2u8][..]);
let candidate = candidate.forget_aligned();
// SAFETY: `&[u8]` consists entirely of initialized bytes.
let candidate = unsafe { candidate.assume_initialized() };
// SAFETY:
// - The cast preserves address and size. As a result, the cast will address
// the same bytes as `c`.
// - The cast preserves provenance.
// - Neither the input nor output types contain any `UnsafeCell`s.
let candidate = unsafe { candidate.cast_unsized_unchecked(|p| p.cast::<Two>()) };
// SAFETY: `candidate`'s referent is as-initialized as `Two`.
let candidate = unsafe { candidate.assume_initialized() };
let is_bit_valid = <Two as imp::TryFromBytes>::is_bit_valid(candidate);
assert!(!is_bit_valid);
}
#[derive(imp::Immutable, imp::TryFromBytes)]
#[repr(C)]
union BoolAndZst {
a: bool,
b: (),
}
#[test]
fn bool_and_zst() {
// FIXME(#5): Use `try_transmute` in this test once it's available.
let candidate = ::zerocopy::Ptr::from_ref(&[2u8][..]);
let candidate = candidate.forget_aligned();
// SAFETY: `&[u8]` consists entirely of initialized bytes.
let candidate = unsafe { candidate.assume_initialized() };
// SAFETY:
// - The cast preserves address and size. As a result, the cast will address
// the same bytes as `c`.
// - The cast preserves provenance.
// - Neither the input nor output types contain any `UnsafeCell`s.
let candidate = unsafe { candidate.cast_unsized_unchecked(|p| p.cast::<BoolAndZst>()) };
// SAFETY: `candidate`'s referent is fully initialized.
let candidate = unsafe { candidate.assume_initialized() };
let is_bit_valid = <BoolAndZst as imp::TryFromBytes>::is_bit_valid(candidate);
assert!(is_bit_valid);
}
#[derive(imp::FromBytes)]
#[repr(C)]
union MaybeFromBytes<T: imp::Copy> {
t: T,
}
#[test]
fn test_maybe_from_bytes() {
// When deriving `FromBytes` on a type with no generic parameters, we emit a
// trivial `is_bit_valid` impl that always returns true. This test confirms
// that we *don't* spuriously do that when generic parameters are present.
let candidate = ::zerocopy::Ptr::from_ref(&[2u8][..]);
let candidate = candidate.bikeshed_recall_initialized_from_bytes();
// SAFETY:
// - The cast preserves address and size. As a result, the cast will address
// the same bytes as `c`.
// - The cast preserves provenance.
// - Neither the input nor output types contain any `UnsafeCell`s.
let candidate =
unsafe { candidate.cast_unsized_unchecked(|p| p.cast::<MaybeFromBytes<bool>>()) };
// SAFETY: `[u8]` consists entirely of initialized bytes.
let candidate = unsafe { candidate.assume_initialized() };
let is_bit_valid = <MaybeFromBytes<bool> as imp::TryFromBytes>::is_bit_valid(candidate);
imp::assert!(!is_bit_valid);
}
#[derive(imp::Immutable, imp::TryFromBytes)]
#[repr(C)]
union TypeParams<'a, T: imp::Copy, I: imp::Iterator>
where
I::Item: imp::Copy,
{
a: I::Item,
b: u8,
c: imp::PhantomData<&'a [u8]>,
d: imp::PhantomData<&'static str>,
e: imp::PhantomData<imp::String>,
f: T,
}
util_assert_impl_all!(TypeParams<'static, (), imp::IntoIter<()>>: imp::TryFromBytes);
util_assert_impl_all!(TypeParams<'static, util::AU16, imp::IntoIter<()>>: imp::TryFromBytes);
util_assert_impl_all!(TypeParams<'static, [util::AU16; 2], imp::IntoIter<()>>: imp::TryFromBytes);
// Deriving `imp::TryFromBytes` should work if the union has bounded parameters.
#[derive(imp::Immutable, imp::TryFromBytes)]
#[repr(C)]
union WithParams<'a: 'b, 'b: 'a, T: 'a + 'b + imp::TryFromBytes, const N: usize>
where
'a: 'b,
'b: 'a,
T: 'a + 'b + imp::TryFromBytes + imp::Copy,
{
a: imp::PhantomData<&'a &'b ()>,
b: T,
}
util_assert_impl_all!(WithParams<'static, 'static, u8, 42>: imp::TryFromBytes);
#[derive(Clone, Copy, imp::TryFromBytes, imp::Immutable)]
struct A;
#[derive(imp::TryFromBytes)]
union B {
a: A,
}

View File

@@ -0,0 +1,77 @@
// Copyright 2019 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.
// See comment in `include.rs` for why we disable the prelude.
#![no_implicit_prelude]
#![allow(warnings)]
include!("include.rs");
// A union is `Unaligned` if:
// - `repr(align)` is no more than 1 and either
// - `repr(C)` or `repr(transparent)` and
// - all fields `Unaligned`
// - `repr(packed)`
#[derive(imp::Unaligned)]
#[repr(C)]
union Foo {
a: imp::u8,
}
util_assert_impl_all!(Foo: imp::Unaligned);
// Transparent unions are unstable; see issue #60405
// <https://github.com/rust-lang/rust/issues/60405> for more information.
// #[derive(Unaligned)]
// #[repr(transparent)]
// union Bar {
// a: u8,
// }
// is_unaligned!(Bar);
#[derive(imp::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,
}
util_assert_impl_all!(Baz: imp::Unaligned);
#[derive(imp::Unaligned)]
#[repr(C, align(1))]
union FooAlign {
a: imp::u8,
}
util_assert_impl_all!(FooAlign: imp::Unaligned);
#[derive(imp::Unaligned)]
#[repr(C)]
union TypeParams<'a, T: imp::Copy, I: imp::Iterator>
where
I::Item: imp::Copy,
{
a: T,
c: I::Item,
d: u8,
e: imp::PhantomData<&'a [imp::u8]>,
f: imp::PhantomData<&'static imp::str>,
g: imp::PhantomData<imp::String>,
}
util_assert_impl_all!(TypeParams<'static, (), imp::IntoIter<()>>: imp::Unaligned);

View File

@@ -0,0 +1,33 @@
// Copyright 2025 The Fuchsia Authors
//
// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
// This file may not be copied, modified, or distributed except according to
// those terms.
// See comment in `include.rs` for why we disable the prelude.
#![no_implicit_prelude]
#![allow(warnings)]
include!("include.rs");
// Test to make sure that all of our derives are compatible with `UnsafeCell`s.
//
// We test both `FromBytes` and `FromZeros`, as the `FromBytes` implied derive
// of `TryFromBytes` emits a trivial `is_bit_valid` impl - we want to test the
// non-trivial impl, which deriving `FromZeros` accomplishes.
#[derive(imp::FromBytes, imp::IntoBytes, imp::KnownLayout, imp::Unaligned)]
#[repr(C)]
struct StructFromBytes(imp::UnsafeCell<u8>);
#[derive(imp::FromZeros, imp::IntoBytes, imp::KnownLayout, imp::Unaligned)]
#[repr(C)]
struct StructFromZeros(imp::UnsafeCell<bool>);
#[derive(imp::FromZeros, imp::IntoBytes, imp::KnownLayout, imp::Unaligned)]
#[repr(u8)]
enum EnumFromZeros {
A(imp::UnsafeCell<bool>),
}