diff --git a/src/lib.rs b/src/lib.rs index a373d3cf51..42a62243c4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1244,7 +1244,8 @@ pub unsafe trait TryFromBytes { // SAFETY: `candidate` has no uninitialized sub-ranges because it // derived from `bytes: &[u8]`, and is therefore at least as-initialized // as `Self`. - let candidate = unsafe { candidate.assume_as_initialized() }; + let candidate = + unsafe { candidate.assume_validity::() }; // This call may panic. If that happens, it doesn't cause any soundness // issues, as we have not generated any invalid state which we need to diff --git a/src/macros.rs b/src/macros.rs index a1512cedbd..a1eb2a36b1 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -146,7 +146,7 @@ macro_rules! unsafe_impl { // SAFETY: The caller has promised that the referenced memory region // will contain a valid `$repr`. - let $candidate = unsafe { candidate.assume_valid() }; + let $candidate = unsafe { candidate.assume_validity::() }; $is_bit_valid } }; @@ -166,7 +166,7 @@ macro_rules! unsafe_impl { // SAFETY: The caller has promised that `$repr` is as-initialized as // `Self`. - let $candidate = unsafe { $candidate.assume_as_initialized() }; + let $candidate = unsafe { $candidate.assume_validity::() }; $is_bit_valid } diff --git a/src/pointer/mod.rs b/src/pointer/mod.rs index a253255d74..34f1d204bf 100644 --- a/src/pointer/mod.rs +++ b/src/pointer/mod.rs @@ -40,7 +40,7 @@ where if T::is_bit_valid(self.forget_aligned()) { // SAFETY: If `T::is_bit_valid`, code may assume that `self` // contains a bit-valid instance of `Self`. - Some(unsafe { self.assume_valid() }) + Some(unsafe { self.assume_validity::() }) } else { None } @@ -82,7 +82,7 @@ where { // SAFETY: The alignment of `T` is 1 and thus is always aligned // because `T: Unaligned`. - let ptr = unsafe { self.assume_aligned() }; + let ptr = unsafe { self.assume_alignment::() }; ptr.as_ref() } } diff --git a/src/pointer/ptr.rs b/src/pointer/ptr.rs index 7f75e30409..c7d2a16ce4 100644 --- a/src/pointer/ptr.rs +++ b/src/pointer/ptr.rs @@ -458,51 +458,69 @@ mod _transitions { T: 'a + ?Sized, I: Invariants, { - /// Assumes that `Ptr`'s referent is validly-aligned for `T`. + /// Assumes that `Ptr`'s referent is validly-aligned for `T` if required + /// by `A`. /// /// # Safety /// /// The caller promises that `Ptr`'s referent conforms to the alignment - /// invariant of `T`. + /// invariant of `T` if required by `A`. #[inline] - pub(crate) unsafe fn assume_aligned( + pub(crate) unsafe fn assume_alignment( self, - ) -> Ptr<'a, T, (I::Aliasing, invariant::Aligned, I::Validity)> { + ) -> Ptr<'a, T, (I::Aliasing, A, I::Validity)> { // SAFETY: The caller promises that `self`'s referent is - // well-aligned for `T`. + // well-aligned for `T` if required by `A` . unsafe { Ptr::from_ptr(self) } } - /// Assumes that `Ptr`'s referent is as-initialized as `T`. + /// Assumes that `Ptr`'s referent conforms to the validity requirement + /// of `V`. /// /// # Safety /// - /// The caller promises that `Ptr`'s referent conforms to the - /// [`invariant::AsInitialized`] invariant (see documentation there). + /// The caller promises that `Ptr`'s referent conforms to the validity + /// requirement of `V`. + #[doc(hidden)] + #[inline] + pub unsafe fn assume_validity( + self, + ) -> Ptr<'a, T, (I::Aliasing, I::Alignment, V)> { + // SAFETY: The caller promises that `self`'s referent conforms to + // the validity requirement of `V`. + unsafe { Ptr::from_ptr(self) } + } + + /// A shorthand for `self.assume_validity()`. + /// + /// # Safety + /// + /// The caller promises to uphold the safety preconditions of + /// `self.assume_validity()`. #[doc(hidden)] #[inline] pub unsafe fn assume_as_initialized( self, ) -> Ptr<'a, T, (I::Aliasing, I::Alignment, invariant::AsInitialized)> { - // SAFETY: The caller promises that `self`'s referent only contains - // uninitialized bytes in a subset of the uninitialized ranges in - // `T`. for `T`. - unsafe { Ptr::from_ptr(self) } + // SAFETY: The caller has promised to uphold the safety + // preconditions. + unsafe { self.assume_validity::() } } - /// Assumes that `Ptr`'s referent is validly initialized for `T`. + /// A shorthand for `self.assume_validity()`. /// /// # Safety /// - /// The caller promises that `Ptr`'s referent conforms to the - /// bit validity invariants on `T`. + /// The caller promises to uphold the safety preconditions of + /// `self.assume_validity()`. + #[doc(hidden)] #[inline] - pub(crate) unsafe fn assume_valid( + pub unsafe fn assume_valid( self, ) -> Ptr<'a, T, (I::Aliasing, I::Alignment, invariant::Valid)> { - // SAFETY: The caller promises that `self`'s referent is bit-valid - // for `T`. - unsafe { Ptr::from_ptr(self) } + // SAFETY: The caller has promised to uphold the safety + // preconditions. + unsafe { self.assume_validity::() } } /// Forgets that `Ptr`'s referent is validly-aligned for `T`. diff --git a/zerocopy-derive/src/lib.rs b/zerocopy-derive/src/lib.rs index a1dca02875..9a3cc4ac90 100644 --- a/zerocopy-derive/src/lib.rs +++ b/zerocopy-derive/src/lib.rs @@ -36,7 +36,7 @@ use { quote::quote, syn::{ parse_quote, Data, DataEnum, DataStruct, DataUnion, DeriveInput, Error, Expr, ExprLit, - GenericParam, Ident, Lit, + GenericParam, Ident, Index, Lit, }, }; @@ -268,9 +268,7 @@ pub fn derive_try_from_bytes(ts: proc_macro::TokenStream) -> proc_macro::TokenSt let ast = syn::parse_macro_input!(ts as DeriveInput); match &ast.data { Data::Struct(strct) => derive_try_from_bytes_struct(&ast, strct), - Data::Enum(_) => { - Error::new_spanned(&ast, "TryFromBytes not supported on enum types").to_compile_error() - } + Data::Enum(enm) => derive_try_from_bytes_enum(&ast, enm), Data::Union(unn) => derive_try_from_bytes_union(&ast, unn), } .into() @@ -401,6 +399,147 @@ const STRUCT_UNION_ALLOWED_REPR_COMBINATIONS: &[&[StructRepr]] = &[ &[StructRepr::C, StructRepr::Packed], ]; +fn derive_try_from_bytes_enum(ast: &DeriveInput, enm: &DataEnum) -> proc_macro2::TokenStream { + if !enm.is_fieldless() { + return Error::new_spanned(ast, "only field-less enums can implement TryFromBytes") + .to_compile_error(); + } + + let reprs = try_or_print!(ENUM_TRY_FROM_BYTES_CFG.validate_reprs(ast)); + let discriminant_type = match reprs.as_slice() { + [EnumRepr::U8] => quote!(u8), + [EnumRepr::U16] => quote!(u16), + [EnumRepr::U32] => quote!(u32), + [EnumRepr::U64] => quote!(u64), + [EnumRepr::Usize] => quote!(usize), + [EnumRepr::I8] => quote!(i8), + [EnumRepr::I16] => quote!(i16), + [EnumRepr::I32] => quote!(i32), + [EnumRepr::I64] => quote!(i64), + [EnumRepr::Isize] => quote!(isize), + // `validate_reprs` has already validated that it's one of the preceding + // patterns. + _ => unreachable!(), + }; + + let discriminant_exprs = enm.variants.iter().scan(Discriminant::default(), |disc, var| { + Some(disc.update_and_generate_expr(&var.discriminant)) + }); + let extras = Some(quote!( + // SAFETY: We use `is_bit_valid` to validate that the bit pattern + // corresponds to one of the C-like enum's variant discriminants. + // Thus, this is a sound implementation of `is_bit_valid`. + fn is_bit_valid( + candidate: ::zerocopy::Ptr< + '_, + Self, + ( + ::zerocopy::pointer::invariant::Shared, + ::zerocopy::pointer::invariant::AnyAlignment, + ::zerocopy::pointer::invariant::AsInitialized, + ), + >, + ) -> bool { + // SAFETY: + // - `cast` is implemented as required. + // - Since we cast to the type specified by `Self`'s repr, `p`'s + // referent and the referent of the returned pointer have the + // same size. + let discriminant = unsafe { candidate.cast_unsized(|p: *mut Self| p as *mut ::zerocopy::macro_util::core_reexport::primitive::#discriminant_type) }; + // SAFETY: Since `candidate` has the invariant `AsInitialized`, + // we know that `candidate`'s referent (and thus + // `discriminant`'s referent) is as-initialized as `Self`. Since + // `Self`'s repr is the same type as `discriminant`, we know + // that `discriminant`'s referent satisfies the as-initialized + // property. + let discriminant = unsafe { discriminant.assume_valid() }; + let discriminant = discriminant.read_unaligned(); + + false #(|| (discriminant == (#discriminant_exprs)))* + } + )); + impl_block(ast, enm, Trait::TryFromBytes, RequireBoundedFields::Yes, false, None, extras) +} + +// Enum variant discriminants can be manually set not only as literal values, +// but as arbitrary const expressions. In order to handle this, we keep track of +// the most-recently-seen expression and a count of how many variants have been +// encountered since then. +// +// #[repr(u8)] +// enum Foo { +// A, // 0 +// B = 5, // 5 +// C, // 6 +// D = 1 + 1, // 2 +// E, // 3 +// } +// +// Note: Default::default does the right thing (initializes to { None, 0 }). +#[derive(Default, Copy, Clone)] +struct Discriminant<'a> { + // The most-recently-set explicit discriminant. + previous: Option<&'a Expr>, + // When the next variant is encountered, what offset should be used compared + // to `previous` to determine the variant's discriminant? + next_offset: usize, +} + +impl<'a> Discriminant<'a> { + /// Called when encountering a variant with discriminant set to `ast`. + /// Updates `self` in preparation for the next variant and generates an + /// expression which will evaluate to the numeric value this variant's + /// discriminant. + fn update_and_generate_expr( + &mut self, + ast: &'a Option<(syn::token::Eq, Expr)>, + ) -> proc_macro2::TokenStream { + match ast.as_ref().map(|(_eq, expr)| expr) { + Some(expr) => { + self.previous = Some(expr); + self.next_offset = 1; + quote!(#expr) + } + None => { + let previous = self.previous.iter(); + // Use `Index` instead of `usize` so that the number is + // formatted just as `0` rather than as `0usize`; the latter + // syntax is only valid if the repr is `usize`; otherwise, + // comparison will result in a type mismatch. + let offset = Index::from(self.next_offset); + let tokens = quote!(#(#previous +)* #offset); + + self.next_offset += 1; + tokens + } + } + } +} + +#[rustfmt::skip] +const ENUM_TRY_FROM_BYTES_CFG: Config = { + use EnumRepr::*; + Config { + allowed_combinations_message: r#"TryFromBytes requires repr of "u8", "u16", "u32", "u64", "usize", "i8", or "i16", "i32", "i64", or "isize""#, + derive_unaligned: false, + allowed_combinations: &[ + &[U8], + &[U16], + &[U32], + &[U64], + &[Usize], + &[I8], + &[I16], + &[I32], + &[I64], + &[Isize], + ], + disallowed_but_legal_combinations: &[ + &[C], + ], + } +}; + // A struct is `FromZeros` if: // - all fields are `FromZeros` diff --git a/zerocopy-derive/tests/enum_try_from_bytes.rs b/zerocopy-derive/tests/enum_try_from_bytes.rs new file mode 100644 index 0000000000..f4a99de31f --- /dev/null +++ b/zerocopy-derive/tests/enum_try_from_bytes.rs @@ -0,0 +1,126 @@ +// Copyright 2023 The Fuchsia Authors +// +// Licensed under a BSD-style license , Apache License, Version 2.0 +// , or the MIT +// license , at your option. +// This file may not be copied, modified, or distributed except according to +// those terms. + +#![allow(warnings)] + +use std::convert::TryFrom; + +mod util; + +use { + static_assertions::assert_impl_all, + zerocopy::{IntoBytes, KnownLayout, TryFromBytes}, +}; + +#[derive(Eq, PartialEq, Debug, KnownLayout, TryFromBytes)] +#[repr(u8)] +enum Foo { + A, +} + +assert_impl_all!(Foo: TryFromBytes); + +#[test] +fn test_foo() { + assert_eq!(Foo::try_from_ref(&[0]), Some(&Foo::A)); + assert_eq!(Foo::try_from_ref(&[]), None); + assert_eq!(Foo::try_from_ref(&[1]), None); + assert_eq!(Foo::try_from_ref(&[0, 0]), None); +} + +#[derive(Eq, PartialEq, Debug, KnownLayout, TryFromBytes)] +#[repr(u16)] +enum Bar { + A = 0, +} + +assert_impl_all!(Bar: TryFromBytes); + +#[test] +fn test_bar() { + assert_eq!(Bar::try_from_ref(&[0, 0]), Some(&Bar::A)); + assert_eq!(Bar::try_from_ref(&[]), None); + assert_eq!(Bar::try_from_ref(&[0]), None); + assert_eq!(Bar::try_from_ref(&[0, 1]), None); + assert_eq!(Bar::try_from_ref(&[0, 0, 0]), None); +} + +#[derive(Eq, PartialEq, Debug, KnownLayout, TryFromBytes)] +#[repr(u32)] +enum Baz { + A = 1, + B = 0, +} + +assert_impl_all!(Baz: TryFromBytes); + +#[test] +fn test_baz() { + assert_eq!(Baz::try_from_ref(1u32.as_bytes()), Some(&Baz::A)); + assert_eq!(Baz::try_from_ref(0u32.as_bytes()), Some(&Baz::B)); + assert_eq!(Baz::try_from_ref(&[]), None); + assert_eq!(Baz::try_from_ref(&[0]), None); + assert_eq!(Baz::try_from_ref(&[0, 0]), None); + assert_eq!(Baz::try_from_ref(&[0, 0, 0]), None); + assert_eq!(Baz::try_from_ref(&[0, 0, 0, 0, 0]), None); +} + +// 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, KnownLayout, TryFromBytes)] +#[repr(i8)] +enum Blah { + A = 1, + B = 0, + C = 1 + 2, + D = 3 + THREE, +} + +assert_impl_all!(Blah: TryFromBytes); + +#[test] +fn test_blah() { + assert_eq!(Blah::try_from_ref(1i8.as_bytes()), Some(&Blah::A)); + assert_eq!(Blah::try_from_ref(0i8.as_bytes()), Some(&Blah::B)); + assert_eq!(Blah::try_from_ref(3i8.as_bytes()), Some(&Blah::C)); + assert_eq!(Blah::try_from_ref(6i8.as_bytes()), Some(&Blah::D)); + assert_eq!(Blah::try_from_ref(&[]), None); + assert_eq!(Blah::try_from_ref(&[4]), None); + assert_eq!(Blah::try_from_ref(&[0, 0]), None); +} + +#[derive(Eq, PartialEq, Debug, KnownLayout, TryFromBytes)] +#[repr(u8)] +enum FieldlessButNotUnitOnly { + A, + B(), + C {}, +} + +#[test] +fn test_fieldless_but_not_unit_only() { + assert_eq!( + FieldlessButNotUnitOnly::try_from_ref(0u8.as_bytes()), + Some(&FieldlessButNotUnitOnly::A) + ); + assert_eq!( + FieldlessButNotUnitOnly::try_from_ref(1u8.as_bytes()), + Some(&FieldlessButNotUnitOnly::B()) + ); + assert_eq!( + FieldlessButNotUnitOnly::try_from_ref(2u8.as_bytes()), + Some(&FieldlessButNotUnitOnly::C {}) + ); + assert_eq!(FieldlessButNotUnitOnly::try_from_ref(&[]), None); + assert_eq!(FieldlessButNotUnitOnly::try_from_ref(&[3]), None); + assert_eq!(FieldlessButNotUnitOnly::try_from_ref(&[0, 0]), None); +} diff --git a/zerocopy-derive/tests/ui-msrv/enum.stderr b/zerocopy-derive/tests/ui-msrv/enum.stderr index e97429d17a..d9ec22c2f4 100644 --- a/zerocopy-derive/tests/ui-msrv/enum.stderr +++ b/zerocopy-derive/tests/ui-msrv/enum.stderr @@ -1,70 +1,34 @@ -error: TryFromBytes not supported on enum types - --> tests/ui-msrv/enum.rs:19:1 - | -19 | / #[repr("foo")] -20 | | enum Generic1 { -21 | | A, -22 | | } - | |_^ - error: unrecognized representation hint --> tests/ui-msrv/enum.rs:19:8 | 19 | #[repr("foo")] | ^^^^^ -error: TryFromBytes not supported on enum types - --> tests/ui-msrv/enum.rs:25:1 - | -25 | / #[repr(foo)] -26 | | enum Generic2 { -27 | | A, -28 | | } - | |_^ - error: unrecognized representation hint --> tests/ui-msrv/enum.rs:25:8 | 25 | #[repr(foo)] | ^^^ -error: TryFromBytes not supported on enum types - --> tests/ui-msrv/enum.rs:31:1 - | -31 | / #[repr(transparent)] -32 | | enum Generic3 { -33 | | A, -34 | | } - | |_^ - error: unsupported representation for deriving zerocopy trait(s) on an enum --> tests/ui-msrv/enum.rs:31:8 | 31 | #[repr(transparent)] | ^^^^^^^^^^^ -error: TryFromBytes not supported on enum types - --> tests/ui-msrv/enum.rs:37:1 - | -37 | / #[repr(u8, u16)] -38 | | enum Generic4 { -39 | | A, -40 | | } - | |_^ - error: conflicting representation hints --> tests/ui-msrv/enum.rs:37:1 | 37 | #[repr(u8, u16)] | ^ -error: TryFromBytes not supported on enum types - --> tests/ui-msrv/enum.rs:43:1 +error: must have a non-align #[repr(...)] attribute in order to guarantee this type's memory layout + --> tests/ui-msrv/enum.rs:42:10 | -43 | / enum Generic5 { -44 | | A, -45 | | } - | |_^ +42 | #[derive(TryFromBytes, FromZeros, FromBytes)] + | ^^^^^^^^^^^^ + | + = note: this error originates in the derive macro `TryFromBytes` (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/enum.rs:42:24 @@ -82,238 +46,203 @@ error: must have a non-align #[repr(...)] attribute in order to guarantee this t | = note: this error originates in the derive macro `FromBytes` (in Nightly builds, run with -Z macro-backtrace for more info) -error: TryFromBytes not supported on enum types - --> tests/ui-msrv/enum.rs:70:1 +error: must have a non-align #[repr(...)] attribute in order to guarantee this type's memory layout + --> tests/ui-msrv/enum.rs:69:10 | -70 | / enum FromZeros1 { -71 | | A(u8), -72 | | } - | |_^ - -error: only field-less enums can implement FromZeros - --> tests/ui-msrv/enum.rs:70:1 +69 | #[derive(TryFromBytes)] + | ^^^^^^^^^^^^ | -70 | / enum FromZeros1 { -71 | | A(u8), -72 | | } - | |_^ + = note: this error originates in the derive macro `TryFromBytes` (in Nightly builds, run with -Z macro-backtrace for more info) -error: TryFromBytes not supported on enum types - --> tests/ui-msrv/enum.rs:75:1 +error: TryFromBytes requires repr of "u8", "u16", "u32", "u64", "usize", "i8", or "i16", "i32", "i64", or "isize" + --> tests/ui-msrv/enum.rs:75:8 | -75 | / enum FromZeros2 { -76 | | A, -77 | | B(u8), -78 | | } - | |_^ - -error: only field-less enums can implement FromZeros - --> tests/ui-msrv/enum.rs:75:1 - | -75 | / enum FromZeros2 { -76 | | A, -77 | | B(u8), -78 | | } - | |_^ +75 | #[repr(C)] + | ^ -error: TryFromBytes not supported on enum types +error: only field-less enums can implement TryFromBytes --> tests/ui-msrv/enum.rs:81:1 | -81 | / enum FromZeros3 { -82 | | A = 1, -83 | | B, +81 | / #[repr(u8)] +82 | | enum TryFromBytes3 { +83 | | A(u8), 84 | | } | |_^ -error: must have a non-align #[repr(...)] attribute in order to guarantee this type's memory layout - --> tests/ui-msrv/enum.rs:80:24 - | -80 | #[derive(TryFromBytes, FromZeros)] - | ^^^^^^^^^ +error: only field-less enums can implement TryFromBytes + --> tests/ui-msrv/enum.rs:91:1 | - = note: this error originates in the derive macro `FromZeros` (in Nightly builds, run with -Z macro-backtrace for more info) +91 | / enum FromZeros1 { +92 | | A(u8), +93 | | } + | |_^ -error: TryFromBytes not supported on enum types +error: only field-less enums can implement FromZeros --> tests/ui-msrv/enum.rs:91:1 | -91 | / #[repr(C)] -92 | | enum FromBytes1 { -93 | | A, -94 | | } +91 | / enum FromZeros1 { +92 | | A(u8), +93 | | } | |_^ -error: FromBytes requires repr of "u8", "u16", "i8", or "i16" - --> tests/ui-msrv/enum.rs:91:8 +error: only field-less enums can implement TryFromBytes + --> tests/ui-msrv/enum.rs:96:1 | -91 | #[repr(C)] - | ^ - -error: TryFromBytes not supported on enum types - --> tests/ui-msrv/enum.rs:97:1 - | -97 | / #[repr(usize)] -98 | | enum FromBytes2 { -99 | | A, -100 | | } - | |_^ +96 | / enum FromZeros2 { +97 | | A, +98 | | B(u8), +99 | | } + | |_^ -error: FromBytes requires repr of "u8", "u16", "i8", or "i16" - --> tests/ui-msrv/enum.rs:97:8 +error: only field-less enums can implement FromZeros + --> tests/ui-msrv/enum.rs:96:1 | -97 | #[repr(usize)] - | ^^^^^ +96 | / enum FromZeros2 { +97 | | A, +98 | | B(u8), +99 | | } + | |_^ -error: TryFromBytes not supported on enum types - --> tests/ui-msrv/enum.rs:103:1 +error: must have a non-align #[repr(...)] attribute in order to guarantee this type's memory layout + --> tests/ui-msrv/enum.rs:101:10 + | +101 | #[derive(TryFromBytes, FromZeros)] + | ^^^^^^^^^^^^ | -103 | / #[repr(isize)] -104 | | enum FromBytes3 { -105 | | A, -106 | | } - | |_^ + = note: this error originates in the derive macro `TryFromBytes` (in Nightly builds, run with -Z macro-backtrace for more info) -error: FromBytes requires repr of "u8", "u16", "i8", or "i16" - --> tests/ui-msrv/enum.rs:103:8 +error: must have a non-align #[repr(...)] attribute in order to guarantee this type's memory layout + --> tests/ui-msrv/enum.rs:101:24 | -103 | #[repr(isize)] - | ^^^^^ +101 | #[derive(TryFromBytes, FromZeros)] + | ^^^^^^^^^ + | + = note: this error originates in the derive macro `FromZeros` (in Nightly builds, run with -Z macro-backtrace for more info) -error: TryFromBytes not supported on enum types - --> tests/ui-msrv/enum.rs:109:1 +error: TryFromBytes requires repr of "u8", "u16", "u32", "u64", "usize", "i8", or "i16", "i32", "i64", or "isize" + --> tests/ui-msrv/enum.rs:112:8 | -109 | / #[repr(u32)] -110 | | enum FromBytes4 { -111 | | A, -112 | | } - | |_^ +112 | #[repr(C)] + | ^ error: FromBytes requires repr of "u8", "u16", "i8", or "i16" - --> tests/ui-msrv/enum.rs:109:8 + --> tests/ui-msrv/enum.rs:112:8 | -109 | #[repr(u32)] - | ^^^ +112 | #[repr(C)] + | ^ -error: TryFromBytes not supported on enum types - --> tests/ui-msrv/enum.rs:115:1 +error: FromBytes requires repr of "u8", "u16", "i8", or "i16" + --> tests/ui-msrv/enum.rs:118:8 | -115 | / #[repr(i32)] -116 | | enum FromBytes5 { -117 | | A, -118 | | } - | |_^ +118 | #[repr(usize)] + | ^^^^^ error: FromBytes requires repr of "u8", "u16", "i8", or "i16" - --> tests/ui-msrv/enum.rs:115:8 + --> tests/ui-msrv/enum.rs:124:8 | -115 | #[repr(i32)] - | ^^^ +124 | #[repr(isize)] + | ^^^^^ -error: TryFromBytes not supported on enum types - --> tests/ui-msrv/enum.rs:121:1 +error: FromBytes requires repr of "u8", "u16", "i8", or "i16" + --> tests/ui-msrv/enum.rs:130:8 | -121 | / #[repr(u64)] -122 | | enum FromBytes6 { -123 | | A, -124 | | } - | |_^ +130 | #[repr(u32)] + | ^^^ error: FromBytes requires repr of "u8", "u16", "i8", or "i16" - --> tests/ui-msrv/enum.rs:121:8 + --> tests/ui-msrv/enum.rs:136:8 | -121 | #[repr(u64)] +136 | #[repr(i32)] | ^^^ -error: TryFromBytes not supported on enum types - --> tests/ui-msrv/enum.rs:127:1 +error: FromBytes requires repr of "u8", "u16", "i8", or "i16" + --> tests/ui-msrv/enum.rs:142:8 | -127 | / #[repr(i64)] -128 | | enum FromBytes7 { -129 | | A, -130 | | } - | |_^ +142 | #[repr(u64)] + | ^^^ error: FromBytes requires repr of "u8", "u16", "i8", or "i16" - --> tests/ui-msrv/enum.rs:127:8 + --> tests/ui-msrv/enum.rs:148:8 | -127 | #[repr(i64)] +148 | #[repr(i64)] | ^^^ error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1))) - --> tests/ui-msrv/enum.rs:137:8 + --> tests/ui-msrv/enum.rs:158:8 | -137 | #[repr(C)] +158 | #[repr(C)] | ^ error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1))) - --> tests/ui-msrv/enum.rs:143:8 + --> tests/ui-msrv/enum.rs:164:8 | -143 | #[repr(u16)] +164 | #[repr(u16)] | ^^^ error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1))) - --> tests/ui-msrv/enum.rs:149:8 + --> tests/ui-msrv/enum.rs:170:8 | -149 | #[repr(i16)] +170 | #[repr(i16)] | ^^^ error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1))) - --> tests/ui-msrv/enum.rs:155:8 + --> tests/ui-msrv/enum.rs:176:8 | -155 | #[repr(u32)] +176 | #[repr(u32)] | ^^^ error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1))) - --> tests/ui-msrv/enum.rs:161:8 + --> tests/ui-msrv/enum.rs:182:8 | -161 | #[repr(i32)] +182 | #[repr(i32)] | ^^^ error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1))) - --> tests/ui-msrv/enum.rs:167:8 + --> tests/ui-msrv/enum.rs:188:8 | -167 | #[repr(u64)] +188 | #[repr(u64)] | ^^^ error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1))) - --> tests/ui-msrv/enum.rs:173:8 + --> tests/ui-msrv/enum.rs:194:8 | -173 | #[repr(i64)] +194 | #[repr(i64)] | ^^^ error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1))) - --> tests/ui-msrv/enum.rs:179:8 + --> tests/ui-msrv/enum.rs:200:8 | -179 | #[repr(usize)] +200 | #[repr(usize)] | ^^^^^ error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1))) - --> tests/ui-msrv/enum.rs:185:8 + --> tests/ui-msrv/enum.rs:206:8 | -185 | #[repr(isize)] +206 | #[repr(isize)] | ^^^^^ error: cannot derive Unaligned with repr(align(N > 1)) - --> tests/ui-msrv/enum.rs:191:12 + --> tests/ui-msrv/enum.rs:212:12 | -191 | #[repr(u8, align(2))] +212 | #[repr(u8, align(2))] | ^^^^^^^^ error: cannot derive Unaligned with repr(align(N > 1)) - --> tests/ui-msrv/enum.rs:197:12 + --> tests/ui-msrv/enum.rs:218:12 | -197 | #[repr(i8, align(2))] +218 | #[repr(i8, align(2))] | ^^^^^^^^ error: cannot derive Unaligned with repr(align(N > 1)) - --> tests/ui-msrv/enum.rs:203:18 + --> tests/ui-msrv/enum.rs:224:18 | -203 | #[repr(align(1), align(2))] +224 | #[repr(align(1), align(2))] | ^^^^^^^^ error: cannot derive Unaligned with repr(align(N > 1)) - --> tests/ui-msrv/enum.rs:209:8 + --> tests/ui-msrv/enum.rs:230:8 | -209 | #[repr(align(2), align(4))] +230 | #[repr(align(2), align(4))] | ^^^^^^^^ error[E0565]: meta item in `repr` must be an identifier diff --git a/zerocopy-derive/tests/ui-nightly/enum.rs b/zerocopy-derive/tests/ui-nightly/enum.rs index 7b00929312..fa977dd0c1 100644 --- a/zerocopy-derive/tests/ui-nightly/enum.rs +++ b/zerocopy-derive/tests/ui-nightly/enum.rs @@ -62,6 +62,27 @@ enum NoCell2 { Inhabited(u8), } +// +// TryFromBytes errors +// + +#[derive(TryFromBytes)] +enum TryFromBytes1 { + A, +} + +#[derive(TryFromBytes)] +#[repr(C)] +enum TryFromBytes2 { + A, +} + +#[derive(TryFromBytes)] +#[repr(u8)] +enum TryFromBytes3 { + A(u8), +} + // // FromZeros errors // diff --git a/zerocopy-derive/tests/ui-nightly/enum.stderr b/zerocopy-derive/tests/ui-nightly/enum.stderr index 066f035890..0b75b6d666 100644 --- a/zerocopy-derive/tests/ui-nightly/enum.stderr +++ b/zerocopy-derive/tests/ui-nightly/enum.stderr @@ -1,70 +1,34 @@ -error: TryFromBytes not supported on enum types - --> tests/ui-nightly/enum.rs:19:1 - | -19 | / #[repr("foo")] -20 | | enum Generic1 { -21 | | A, -22 | | } - | |_^ - error: unrecognized representation hint --> tests/ui-nightly/enum.rs:19:8 | 19 | #[repr("foo")] | ^^^^^ -error: TryFromBytes not supported on enum types - --> tests/ui-nightly/enum.rs:25:1 - | -25 | / #[repr(foo)] -26 | | enum Generic2 { -27 | | A, -28 | | } - | |_^ - error: unrecognized representation hint --> tests/ui-nightly/enum.rs:25:8 | 25 | #[repr(foo)] | ^^^ -error: TryFromBytes not supported on enum types - --> tests/ui-nightly/enum.rs:31:1 - | -31 | / #[repr(transparent)] -32 | | enum Generic3 { -33 | | A, -34 | | } - | |_^ - error: unsupported representation for deriving zerocopy trait(s) on an enum --> tests/ui-nightly/enum.rs:31:8 | 31 | #[repr(transparent)] | ^^^^^^^^^^^ -error: TryFromBytes not supported on enum types - --> tests/ui-nightly/enum.rs:37:1 - | -37 | / #[repr(u8, u16)] -38 | | enum Generic4 { -39 | | A, -40 | | } - | |_^ - error: conflicting representation hints --> tests/ui-nightly/enum.rs:37:8 | 37 | #[repr(u8, u16)] | ^^^^^^^ -error: TryFromBytes not supported on enum types - --> tests/ui-nightly/enum.rs:43:1 +error: must have a non-align #[repr(...)] attribute in order to guarantee this type's memory layout + --> tests/ui-nightly/enum.rs:42:10 | -43 | / enum Generic5 { -44 | | A, -45 | | } - | |_^ +42 | #[derive(TryFromBytes, FromZeros, FromBytes)] + | ^^^^^^^^^^^^ + | + = note: this error originates in the derive macro `TryFromBytes` (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/enum.rs:42:24 @@ -82,238 +46,203 @@ error: must have a non-align #[repr(...)] attribute in order to guarantee this t | = note: this error originates in the derive macro `FromBytes` (in Nightly builds, run with -Z macro-backtrace for more info) -error: TryFromBytes not supported on enum types - --> tests/ui-nightly/enum.rs:70:1 +error: must have a non-align #[repr(...)] attribute in order to guarantee this type's memory layout + --> tests/ui-nightly/enum.rs:69:10 | -70 | / enum FromZeros1 { -71 | | A(u8), -72 | | } - | |_^ - -error: only field-less enums can implement FromZeros - --> tests/ui-nightly/enum.rs:70:1 +69 | #[derive(TryFromBytes)] + | ^^^^^^^^^^^^ | -70 | / enum FromZeros1 { -71 | | A(u8), -72 | | } - | |_^ + = note: this error originates in the derive macro `TryFromBytes` (in Nightly builds, run with -Z macro-backtrace for more info) -error: TryFromBytes not supported on enum types - --> tests/ui-nightly/enum.rs:75:1 +error: TryFromBytes requires repr of "u8", "u16", "u32", "u64", "usize", "i8", or "i16", "i32", "i64", or "isize" + --> tests/ui-nightly/enum.rs:75:8 | -75 | / enum FromZeros2 { -76 | | A, -77 | | B(u8), -78 | | } - | |_^ - -error: only field-less enums can implement FromZeros - --> tests/ui-nightly/enum.rs:75:1 - | -75 | / enum FromZeros2 { -76 | | A, -77 | | B(u8), -78 | | } - | |_^ +75 | #[repr(C)] + | ^ -error: TryFromBytes not supported on enum types +error: only field-less enums can implement TryFromBytes --> tests/ui-nightly/enum.rs:81:1 | -81 | / enum FromZeros3 { -82 | | A = 1, -83 | | B, +81 | / #[repr(u8)] +82 | | enum TryFromBytes3 { +83 | | A(u8), 84 | | } | |_^ -error: must have a non-align #[repr(...)] attribute in order to guarantee this type's memory layout - --> tests/ui-nightly/enum.rs:80:24 - | -80 | #[derive(TryFromBytes, FromZeros)] - | ^^^^^^^^^ +error: only field-less enums can implement TryFromBytes + --> tests/ui-nightly/enum.rs:91:1 | - = note: this error originates in the derive macro `FromZeros` (in Nightly builds, run with -Z macro-backtrace for more info) +91 | / enum FromZeros1 { +92 | | A(u8), +93 | | } + | |_^ -error: TryFromBytes not supported on enum types +error: only field-less enums can implement FromZeros --> tests/ui-nightly/enum.rs:91:1 | -91 | / #[repr(C)] -92 | | enum FromBytes1 { -93 | | A, -94 | | } +91 | / enum FromZeros1 { +92 | | A(u8), +93 | | } | |_^ -error: FromBytes requires repr of "u8", "u16", "i8", or "i16" - --> tests/ui-nightly/enum.rs:91:8 +error: only field-less enums can implement TryFromBytes + --> tests/ui-nightly/enum.rs:96:1 | -91 | #[repr(C)] - | ^ - -error: TryFromBytes not supported on enum types - --> tests/ui-nightly/enum.rs:97:1 - | -97 | / #[repr(usize)] -98 | | enum FromBytes2 { -99 | | A, -100 | | } - | |_^ +96 | / enum FromZeros2 { +97 | | A, +98 | | B(u8), +99 | | } + | |_^ -error: FromBytes requires repr of "u8", "u16", "i8", or "i16" - --> tests/ui-nightly/enum.rs:97:8 +error: only field-less enums can implement FromZeros + --> tests/ui-nightly/enum.rs:96:1 | -97 | #[repr(usize)] - | ^^^^^ +96 | / enum FromZeros2 { +97 | | A, +98 | | B(u8), +99 | | } + | |_^ -error: TryFromBytes not supported on enum types - --> tests/ui-nightly/enum.rs:103:1 +error: must have a non-align #[repr(...)] attribute in order to guarantee this type's memory layout + --> tests/ui-nightly/enum.rs:101:10 + | +101 | #[derive(TryFromBytes, FromZeros)] + | ^^^^^^^^^^^^ | -103 | / #[repr(isize)] -104 | | enum FromBytes3 { -105 | | A, -106 | | } - | |_^ + = note: this error originates in the derive macro `TryFromBytes` (in Nightly builds, run with -Z macro-backtrace for more info) -error: FromBytes requires repr of "u8", "u16", "i8", or "i16" - --> tests/ui-nightly/enum.rs:103:8 +error: must have a non-align #[repr(...)] attribute in order to guarantee this type's memory layout + --> tests/ui-nightly/enum.rs:101:24 | -103 | #[repr(isize)] - | ^^^^^ +101 | #[derive(TryFromBytes, FromZeros)] + | ^^^^^^^^^ + | + = note: this error originates in the derive macro `FromZeros` (in Nightly builds, run with -Z macro-backtrace for more info) -error: TryFromBytes not supported on enum types - --> tests/ui-nightly/enum.rs:109:1 +error: TryFromBytes requires repr of "u8", "u16", "u32", "u64", "usize", "i8", or "i16", "i32", "i64", or "isize" + --> tests/ui-nightly/enum.rs:112:8 | -109 | / #[repr(u32)] -110 | | enum FromBytes4 { -111 | | A, -112 | | } - | |_^ +112 | #[repr(C)] + | ^ error: FromBytes requires repr of "u8", "u16", "i8", or "i16" - --> tests/ui-nightly/enum.rs:109:8 + --> tests/ui-nightly/enum.rs:112:8 | -109 | #[repr(u32)] - | ^^^ +112 | #[repr(C)] + | ^ -error: TryFromBytes not supported on enum types - --> tests/ui-nightly/enum.rs:115:1 +error: FromBytes requires repr of "u8", "u16", "i8", or "i16" + --> tests/ui-nightly/enum.rs:118:8 | -115 | / #[repr(i32)] -116 | | enum FromBytes5 { -117 | | A, -118 | | } - | |_^ +118 | #[repr(usize)] + | ^^^^^ error: FromBytes requires repr of "u8", "u16", "i8", or "i16" - --> tests/ui-nightly/enum.rs:115:8 + --> tests/ui-nightly/enum.rs:124:8 | -115 | #[repr(i32)] - | ^^^ +124 | #[repr(isize)] + | ^^^^^ -error: TryFromBytes not supported on enum types - --> tests/ui-nightly/enum.rs:121:1 +error: FromBytes requires repr of "u8", "u16", "i8", or "i16" + --> tests/ui-nightly/enum.rs:130:8 | -121 | / #[repr(u64)] -122 | | enum FromBytes6 { -123 | | A, -124 | | } - | |_^ +130 | #[repr(u32)] + | ^^^ error: FromBytes requires repr of "u8", "u16", "i8", or "i16" - --> tests/ui-nightly/enum.rs:121:8 + --> tests/ui-nightly/enum.rs:136:8 | -121 | #[repr(u64)] +136 | #[repr(i32)] | ^^^ -error: TryFromBytes not supported on enum types - --> tests/ui-nightly/enum.rs:127:1 +error: FromBytes requires repr of "u8", "u16", "i8", or "i16" + --> tests/ui-nightly/enum.rs:142:8 | -127 | / #[repr(i64)] -128 | | enum FromBytes7 { -129 | | A, -130 | | } - | |_^ +142 | #[repr(u64)] + | ^^^ error: FromBytes requires repr of "u8", "u16", "i8", or "i16" - --> tests/ui-nightly/enum.rs:127:8 + --> tests/ui-nightly/enum.rs:148:8 | -127 | #[repr(i64)] +148 | #[repr(i64)] | ^^^ error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1))) - --> tests/ui-nightly/enum.rs:137:8 + --> tests/ui-nightly/enum.rs:158:8 | -137 | #[repr(C)] +158 | #[repr(C)] | ^ error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1))) - --> tests/ui-nightly/enum.rs:143:8 + --> tests/ui-nightly/enum.rs:164:8 | -143 | #[repr(u16)] +164 | #[repr(u16)] | ^^^ error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1))) - --> tests/ui-nightly/enum.rs:149:8 + --> tests/ui-nightly/enum.rs:170:8 | -149 | #[repr(i16)] +170 | #[repr(i16)] | ^^^ error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1))) - --> tests/ui-nightly/enum.rs:155:8 + --> tests/ui-nightly/enum.rs:176:8 | -155 | #[repr(u32)] +176 | #[repr(u32)] | ^^^ error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1))) - --> tests/ui-nightly/enum.rs:161:8 + --> tests/ui-nightly/enum.rs:182:8 | -161 | #[repr(i32)] +182 | #[repr(i32)] | ^^^ error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1))) - --> tests/ui-nightly/enum.rs:167:8 + --> tests/ui-nightly/enum.rs:188:8 | -167 | #[repr(u64)] +188 | #[repr(u64)] | ^^^ error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1))) - --> tests/ui-nightly/enum.rs:173:8 + --> tests/ui-nightly/enum.rs:194:8 | -173 | #[repr(i64)] +194 | #[repr(i64)] | ^^^ error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1))) - --> tests/ui-nightly/enum.rs:179:8 + --> tests/ui-nightly/enum.rs:200:8 | -179 | #[repr(usize)] +200 | #[repr(usize)] | ^^^^^ error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1))) - --> tests/ui-nightly/enum.rs:185:8 + --> tests/ui-nightly/enum.rs:206:8 | -185 | #[repr(isize)] +206 | #[repr(isize)] | ^^^^^ error: cannot derive Unaligned with repr(align(N > 1)) - --> tests/ui-nightly/enum.rs:191:12 + --> tests/ui-nightly/enum.rs:212:12 | -191 | #[repr(u8, align(2))] +212 | #[repr(u8, align(2))] | ^^^^^^^^ error: cannot derive Unaligned with repr(align(N > 1)) - --> tests/ui-nightly/enum.rs:197:12 + --> tests/ui-nightly/enum.rs:218:12 | -197 | #[repr(i8, align(2))] +218 | #[repr(i8, align(2))] | ^^^^^^^^ error: cannot derive Unaligned with repr(align(N > 1)) - --> tests/ui-nightly/enum.rs:203:18 + --> tests/ui-nightly/enum.rs:224:18 | -203 | #[repr(align(1), align(2))] +224 | #[repr(align(1), align(2))] | ^^^^^^^^ error: cannot derive Unaligned with repr(align(N > 1)) - --> tests/ui-nightly/enum.rs:209:8 + --> tests/ui-nightly/enum.rs:230:8 | -209 | #[repr(align(2), align(4))] +230 | #[repr(align(2), align(4))] | ^^^^^^^^ error[E0565]: meta item in `repr` must be an identifier diff --git a/zerocopy-derive/tests/ui-stable/enum.stderr b/zerocopy-derive/tests/ui-stable/enum.stderr index bba292af25..2db189f015 100644 --- a/zerocopy-derive/tests/ui-stable/enum.stderr +++ b/zerocopy-derive/tests/ui-stable/enum.stderr @@ -1,70 +1,34 @@ -error: TryFromBytes not supported on enum types - --> tests/ui-stable/enum.rs:19:1 - | -19 | / #[repr("foo")] -20 | | enum Generic1 { -21 | | A, -22 | | } - | |_^ - error: unrecognized representation hint --> tests/ui-stable/enum.rs:19:8 | 19 | #[repr("foo")] | ^^^^^ -error: TryFromBytes not supported on enum types - --> tests/ui-stable/enum.rs:25:1 - | -25 | / #[repr(foo)] -26 | | enum Generic2 { -27 | | A, -28 | | } - | |_^ - error: unrecognized representation hint --> tests/ui-stable/enum.rs:25:8 | 25 | #[repr(foo)] | ^^^ -error: TryFromBytes not supported on enum types - --> tests/ui-stable/enum.rs:31:1 - | -31 | / #[repr(transparent)] -32 | | enum Generic3 { -33 | | A, -34 | | } - | |_^ - error: unsupported representation for deriving zerocopy trait(s) on an enum --> tests/ui-stable/enum.rs:31:8 | 31 | #[repr(transparent)] | ^^^^^^^^^^^ -error: TryFromBytes not supported on enum types - --> tests/ui-stable/enum.rs:37:1 - | -37 | / #[repr(u8, u16)] -38 | | enum Generic4 { -39 | | A, -40 | | } - | |_^ - error: conflicting representation hints --> tests/ui-stable/enum.rs:37:1 | 37 | #[repr(u8, u16)] | ^ -error: TryFromBytes not supported on enum types - --> tests/ui-stable/enum.rs:43:1 +error: must have a non-align #[repr(...)] attribute in order to guarantee this type's memory layout + --> tests/ui-stable/enum.rs:42:10 | -43 | / enum Generic5 { -44 | | A, -45 | | } - | |_^ +42 | #[derive(TryFromBytes, FromZeros, FromBytes)] + | ^^^^^^^^^^^^ + | + = note: this error originates in the derive macro `TryFromBytes` (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/enum.rs:42:24 @@ -82,238 +46,203 @@ error: must have a non-align #[repr(...)] attribute in order to guarantee this t | = note: this error originates in the derive macro `FromBytes` (in Nightly builds, run with -Z macro-backtrace for more info) -error: TryFromBytes not supported on enum types - --> tests/ui-stable/enum.rs:70:1 +error: must have a non-align #[repr(...)] attribute in order to guarantee this type's memory layout + --> tests/ui-stable/enum.rs:69:10 | -70 | / enum FromZeros1 { -71 | | A(u8), -72 | | } - | |_^ - -error: only field-less enums can implement FromZeros - --> tests/ui-stable/enum.rs:70:1 +69 | #[derive(TryFromBytes)] + | ^^^^^^^^^^^^ | -70 | / enum FromZeros1 { -71 | | A(u8), -72 | | } - | |_^ + = note: this error originates in the derive macro `TryFromBytes` (in Nightly builds, run with -Z macro-backtrace for more info) -error: TryFromBytes not supported on enum types - --> tests/ui-stable/enum.rs:75:1 +error: TryFromBytes requires repr of "u8", "u16", "u32", "u64", "usize", "i8", or "i16", "i32", "i64", or "isize" + --> tests/ui-stable/enum.rs:75:8 | -75 | / enum FromZeros2 { -76 | | A, -77 | | B(u8), -78 | | } - | |_^ - -error: only field-less enums can implement FromZeros - --> tests/ui-stable/enum.rs:75:1 - | -75 | / enum FromZeros2 { -76 | | A, -77 | | B(u8), -78 | | } - | |_^ +75 | #[repr(C)] + | ^ -error: TryFromBytes not supported on enum types +error: only field-less enums can implement TryFromBytes --> tests/ui-stable/enum.rs:81:1 | -81 | / enum FromZeros3 { -82 | | A = 1, -83 | | B, +81 | / #[repr(u8)] +82 | | enum TryFromBytes3 { +83 | | A(u8), 84 | | } | |_^ -error: must have a non-align #[repr(...)] attribute in order to guarantee this type's memory layout - --> tests/ui-stable/enum.rs:80:24 - | -80 | #[derive(TryFromBytes, FromZeros)] - | ^^^^^^^^^ +error: only field-less enums can implement TryFromBytes + --> tests/ui-stable/enum.rs:91:1 | - = note: this error originates in the derive macro `FromZeros` (in Nightly builds, run with -Z macro-backtrace for more info) +91 | / enum FromZeros1 { +92 | | A(u8), +93 | | } + | |_^ -error: TryFromBytes not supported on enum types +error: only field-less enums can implement FromZeros --> tests/ui-stable/enum.rs:91:1 | -91 | / #[repr(C)] -92 | | enum FromBytes1 { -93 | | A, -94 | | } +91 | / enum FromZeros1 { +92 | | A(u8), +93 | | } | |_^ -error: FromBytes requires repr of "u8", "u16", "i8", or "i16" - --> tests/ui-stable/enum.rs:91:8 +error: only field-less enums can implement TryFromBytes + --> tests/ui-stable/enum.rs:96:1 | -91 | #[repr(C)] - | ^ - -error: TryFromBytes not supported on enum types - --> tests/ui-stable/enum.rs:97:1 - | -97 | / #[repr(usize)] -98 | | enum FromBytes2 { -99 | | A, -100 | | } - | |_^ +96 | / enum FromZeros2 { +97 | | A, +98 | | B(u8), +99 | | } + | |_^ -error: FromBytes requires repr of "u8", "u16", "i8", or "i16" - --> tests/ui-stable/enum.rs:97:8 +error: only field-less enums can implement FromZeros + --> tests/ui-stable/enum.rs:96:1 | -97 | #[repr(usize)] - | ^^^^^ +96 | / enum FromZeros2 { +97 | | A, +98 | | B(u8), +99 | | } + | |_^ -error: TryFromBytes not supported on enum types - --> tests/ui-stable/enum.rs:103:1 +error: must have a non-align #[repr(...)] attribute in order to guarantee this type's memory layout + --> tests/ui-stable/enum.rs:101:10 + | +101 | #[derive(TryFromBytes, FromZeros)] + | ^^^^^^^^^^^^ | -103 | / #[repr(isize)] -104 | | enum FromBytes3 { -105 | | A, -106 | | } - | |_^ + = note: this error originates in the derive macro `TryFromBytes` (in Nightly builds, run with -Z macro-backtrace for more info) -error: FromBytes requires repr of "u8", "u16", "i8", or "i16" - --> tests/ui-stable/enum.rs:103:8 +error: must have a non-align #[repr(...)] attribute in order to guarantee this type's memory layout + --> tests/ui-stable/enum.rs:101:24 | -103 | #[repr(isize)] - | ^^^^^ +101 | #[derive(TryFromBytes, FromZeros)] + | ^^^^^^^^^ + | + = note: this error originates in the derive macro `FromZeros` (in Nightly builds, run with -Z macro-backtrace for more info) -error: TryFromBytes not supported on enum types - --> tests/ui-stable/enum.rs:109:1 +error: TryFromBytes requires repr of "u8", "u16", "u32", "u64", "usize", "i8", or "i16", "i32", "i64", or "isize" + --> tests/ui-stable/enum.rs:112:8 | -109 | / #[repr(u32)] -110 | | enum FromBytes4 { -111 | | A, -112 | | } - | |_^ +112 | #[repr(C)] + | ^ error: FromBytes requires repr of "u8", "u16", "i8", or "i16" - --> tests/ui-stable/enum.rs:109:8 + --> tests/ui-stable/enum.rs:112:8 | -109 | #[repr(u32)] - | ^^^ +112 | #[repr(C)] + | ^ -error: TryFromBytes not supported on enum types - --> tests/ui-stable/enum.rs:115:1 +error: FromBytes requires repr of "u8", "u16", "i8", or "i16" + --> tests/ui-stable/enum.rs:118:8 | -115 | / #[repr(i32)] -116 | | enum FromBytes5 { -117 | | A, -118 | | } - | |_^ +118 | #[repr(usize)] + | ^^^^^ error: FromBytes requires repr of "u8", "u16", "i8", or "i16" - --> tests/ui-stable/enum.rs:115:8 + --> tests/ui-stable/enum.rs:124:8 | -115 | #[repr(i32)] - | ^^^ +124 | #[repr(isize)] + | ^^^^^ -error: TryFromBytes not supported on enum types - --> tests/ui-stable/enum.rs:121:1 +error: FromBytes requires repr of "u8", "u16", "i8", or "i16" + --> tests/ui-stable/enum.rs:130:8 | -121 | / #[repr(u64)] -122 | | enum FromBytes6 { -123 | | A, -124 | | } - | |_^ +130 | #[repr(u32)] + | ^^^ error: FromBytes requires repr of "u8", "u16", "i8", or "i16" - --> tests/ui-stable/enum.rs:121:8 + --> tests/ui-stable/enum.rs:136:8 | -121 | #[repr(u64)] +136 | #[repr(i32)] | ^^^ -error: TryFromBytes not supported on enum types - --> tests/ui-stable/enum.rs:127:1 +error: FromBytes requires repr of "u8", "u16", "i8", or "i16" + --> tests/ui-stable/enum.rs:142:8 | -127 | / #[repr(i64)] -128 | | enum FromBytes7 { -129 | | A, -130 | | } - | |_^ +142 | #[repr(u64)] + | ^^^ error: FromBytes requires repr of "u8", "u16", "i8", or "i16" - --> tests/ui-stable/enum.rs:127:8 + --> tests/ui-stable/enum.rs:148:8 | -127 | #[repr(i64)] +148 | #[repr(i64)] | ^^^ error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1))) - --> tests/ui-stable/enum.rs:137:8 + --> tests/ui-stable/enum.rs:158:8 | -137 | #[repr(C)] +158 | #[repr(C)] | ^ error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1))) - --> tests/ui-stable/enum.rs:143:8 + --> tests/ui-stable/enum.rs:164:8 | -143 | #[repr(u16)] +164 | #[repr(u16)] | ^^^ error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1))) - --> tests/ui-stable/enum.rs:149:8 + --> tests/ui-stable/enum.rs:170:8 | -149 | #[repr(i16)] +170 | #[repr(i16)] | ^^^ error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1))) - --> tests/ui-stable/enum.rs:155:8 + --> tests/ui-stable/enum.rs:176:8 | -155 | #[repr(u32)] +176 | #[repr(u32)] | ^^^ error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1))) - --> tests/ui-stable/enum.rs:161:8 + --> tests/ui-stable/enum.rs:182:8 | -161 | #[repr(i32)] +182 | #[repr(i32)] | ^^^ error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1))) - --> tests/ui-stable/enum.rs:167:8 + --> tests/ui-stable/enum.rs:188:8 | -167 | #[repr(u64)] +188 | #[repr(u64)] | ^^^ error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1))) - --> tests/ui-stable/enum.rs:173:8 + --> tests/ui-stable/enum.rs:194:8 | -173 | #[repr(i64)] +194 | #[repr(i64)] | ^^^ error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1))) - --> tests/ui-stable/enum.rs:179:8 + --> tests/ui-stable/enum.rs:200:8 | -179 | #[repr(usize)] +200 | #[repr(usize)] | ^^^^^ error: Unaligned requires repr of "u8" or "i8", and no alignment (i.e., repr(align(N > 1))) - --> tests/ui-stable/enum.rs:185:8 + --> tests/ui-stable/enum.rs:206:8 | -185 | #[repr(isize)] +206 | #[repr(isize)] | ^^^^^ error: cannot derive Unaligned with repr(align(N > 1)) - --> tests/ui-stable/enum.rs:191:12 + --> tests/ui-stable/enum.rs:212:12 | -191 | #[repr(u8, align(2))] +212 | #[repr(u8, align(2))] | ^^^^^^^^ error: cannot derive Unaligned with repr(align(N > 1)) - --> tests/ui-stable/enum.rs:197:12 + --> tests/ui-stable/enum.rs:218:12 | -197 | #[repr(i8, align(2))] +218 | #[repr(i8, align(2))] | ^^^^^^^^ error: cannot derive Unaligned with repr(align(N > 1)) - --> tests/ui-stable/enum.rs:203:18 + --> tests/ui-stable/enum.rs:224:18 | -203 | #[repr(align(1), align(2))] +224 | #[repr(align(1), align(2))] | ^^^^^^^^ error: cannot derive Unaligned with repr(align(N > 1)) - --> tests/ui-stable/enum.rs:209:8 + --> tests/ui-stable/enum.rs:230:8 | -209 | #[repr(align(2), align(4))] +230 | #[repr(align(2), align(4))] | ^^^^^^^^ error[E0565]: meta item in `repr` must be an identifier