diff --git a/tests/tests/derive.rs b/tests/tests/derive.rs index 996881be..479a04e6 100644 --- a/tests/tests/derive.rs +++ b/tests/tests/derive.rs @@ -194,6 +194,44 @@ fn test_transparent() { assert!(matches!(Valuable::as_value(&T('a')), Value::Char('a'))); } +#[test] +fn test_derive_generic() { + #[derive(Valuable)] + struct GenericStruct { + value: T, + } + + #[derive(Valuable)] + struct MultiGeneric { + first: T, + second: U, + } + + #[derive(Valuable)] + enum GenericEnum { + Value(T), + Empty, + } + + let s = GenericStruct { value: 42u32 }; + assert_eq!(format!("{:?}", s.as_value()), "GenericStruct { value: 42 }"); + + let m = MultiGeneric { + first: 1u8, + second: "hello", + }; + assert_eq!( + format!("{:?}", m.as_value()), + r#"MultiGeneric { first: 1, second: "hello" }"# + ); + + let e = GenericEnum::Value(true); + assert_eq!(format!("{:?}", e.as_value()), "GenericEnum::Value(true)"); + + let e: GenericEnum = GenericEnum::Empty; + assert_eq!(format!("{:?}", e.as_value()), "GenericEnum::Empty"); +} + #[rustversion::attr(not(stable), ignore)] #[test] fn ui() { diff --git a/tests/tests/ui/not_valuable.stderr b/tests/tests/ui/not_valuable.stderr index d21a1718..84a19932 100644 --- a/tests/tests/ui/not_valuable.stderr +++ b/tests/tests/ui/not_valuable.stderr @@ -5,8 +5,13 @@ error[E0277]: the trait bound `S: Valuable` is not satisfied | -------- required by a bound introduced by this call 6 | struct Struct { 7 | f: Option, - | ^^^^^^^^^ the trait `Valuable` is not implemented for `S` + | ^^^^^^^^^ unsatisfied trait bound | +help: the trait `Valuable` is not implemented for `S` + --> tests/ui/not_valuable.rs:3:1 + | +3 | struct S; + | ^^^^^^^^ = help: the following other types implement trait `Valuable`: &T &[T] @@ -25,8 +30,13 @@ error[E0277]: the trait bound `S: Valuable` is not satisfied 10 | #[derive(Valuable)] | -------- required by a bound introduced by this call 11 | struct Tuple(Option); - | ^^^^^^^^^ the trait `Valuable` is not implemented for `S` + | ^^^^^^^^^ unsatisfied trait bound + | +help: the trait `Valuable` is not implemented for `S` + --> tests/ui/not_valuable.rs:3:1 | + 3 | struct S; + | ^^^^^^^^ = help: the following other types implement trait `Valuable`: &T &[T] @@ -46,8 +56,13 @@ error[E0277]: the trait bound `S: Valuable` is not satisfied | -------- required by a bound introduced by this call 14 | enum Enum { 15 | Struct { f: Option }, - | ^ the trait `Valuable` is not implemented for `S` + | ^ unsatisfied trait bound | +help: the trait `Valuable` is not implemented for `S` + --> tests/ui/not_valuable.rs:3:1 + | + 3 | struct S; + | ^^^^^^^^ = help: the following other types implement trait `Valuable`: &T &[T] @@ -69,8 +84,13 @@ error[E0277]: the trait bound `S: Valuable` is not satisfied | -------- required by a bound introduced by this call ... 16 | Tuple(Option), - | ^ the trait `Valuable` is not implemented for `S` + | ^ unsatisfied trait bound + | +help: the trait `Valuable` is not implemented for `S` + --> tests/ui/not_valuable.rs:3:1 | + 3 | struct S; + | ^^^^^^^^ = help: the following other types implement trait `Valuable`: &T &[T] diff --git a/valuable-derive/src/expand.rs b/valuable-derive/src/expand.rs index 7fe879d5..dc79fc26 100644 --- a/valuable-derive/src/expand.rs +++ b/valuable-derive/src/expand.rs @@ -45,7 +45,15 @@ fn derive_struct( let name = &input.ident; let name_literal = struct_attrs.rename(name); - let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl(); + let mut generics = input.generics.clone(); + for type_param in input.generics.type_params() { + let ident = &type_param.ident; + generics + .make_where_clause() + .predicates + .push(syn::parse_quote!(#ident: ::valuable::Valuable)); + } + let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); let allowed_lints = allowed_lints(); if struct_attrs.transparent() { @@ -350,7 +358,15 @@ fn derive_enum(cx: Context, input: &syn::DeriveInput, data: &syn::DataEnum) -> R ]; }; - let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl(); + let mut generics = input.generics.clone(); + for type_param in input.generics.type_params() { + let ident = &type_param.ident; + generics + .make_where_clause() + .predicates + .push(syn::parse_quote!(#ident: ::valuable::Valuable)); + } + let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); let enumerable_impl = quote! { #[automatically_derived] impl #impl_generics ::valuable::Enumerable for #name #ty_generics #where_clause { diff --git a/valuable/no_atomic.rs b/valuable/no_atomic.rs index 3f0d4eee..47baa5a9 100644 --- a/valuable/no_atomic.rs +++ b/valuable/no_atomic.rs @@ -14,6 +14,7 @@ const NO_ATOMIC_CAS: &[&str] = &[ "riscv32i-unknown-none-elf", "riscv32im-unknown-none-elf", "riscv32imc-unknown-none-elf", + "riscv64im-unknown-none-elf", "thumbv4t-none-eabi", "thumbv5te-none-eabi", "thumbv6m-none-eabi", @@ -22,9 +23,7 @@ const NO_ATOMIC_CAS: &[&str] = &[ const NO_ATOMIC_64: &[&str] = &[ "arm-linux-androideabi", - "armv4t-none-eabi", "armv4t-unknown-linux-gnueabi", - "armv5te-none-eabi", "armv5te-unknown-linux-gnueabi", "armv5te-unknown-linux-musleabi", "armv5te-unknown-linux-uclibceabi", @@ -33,6 +32,9 @@ const NO_ATOMIC_64: &[&str] = &[ "csky-unknown-linux-gnuabiv2hf", "hexagon-unknown-linux-musl", "hexagon-unknown-none-elf", + "hexagon-unknown-qurt", + "loongarch32-unknown-none", + "loongarch32-unknown-none-softfloat", "m68k-unknown-linux-gnu", "m68k-unknown-none-elf", "mips-mti-none-elf", @@ -49,6 +51,7 @@ const NO_ATOMIC_64: &[&str] = &[ "mipsisa32r6-unknown-linux-gnu", "mipsisa32r6el-unknown-linux-gnu", "powerpc-unknown-freebsd", + "powerpc-unknown-helenos", "powerpc-unknown-linux-gnu", "powerpc-unknown-linux-gnuspe", "powerpc-unknown-linux-musl", @@ -78,8 +81,7 @@ const NO_ATOMIC_64: &[&str] = &[ "riscv32imc-unknown-nuttx-elf", "sparc-unknown-linux-gnu", "sparc-unknown-none-elf", - "thumbv4t-none-eabi", - "thumbv5te-none-eabi", + "thumbv6-none-eabi", "thumbv6m-none-eabi", "thumbv6m-nuttx-eabi", "thumbv7em-none-eabi", @@ -103,9 +105,13 @@ const NO_ATOMIC_64: &[&str] = &[ ]; const NO_ATOMIC: &[&str] = &[ + "armv4t-none-eabi", + "armv5te-none-eabi", "avr-none", "bpfeb-unknown-none", "bpfel-unknown-none", "mipsel-sony-psx", "msp430-none-elf", + "thumbv4t-none-eabi", + "thumbv5te-none-eabi", ]; diff --git a/valuable/src/lib.rs b/valuable/src/lib.rs index 255ee5a7..1d440b38 100644 --- a/valuable/src/lib.rs +++ b/valuable/src/lib.rs @@ -107,15 +107,7 @@ //! [`valuable_serde::Serializable`]: https://docs.rs/valuable-serde/latest/valuable_serde/struct.Serializable.html //! [`serde::ser::Serializer`]: https://docs.rs/serde/latest/serde/ser/trait.Serializer.html #![cfg_attr(not(feature = "std"), no_std)] -#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg, doc_cfg_hide))] -#![cfg_attr( - docsrs, - doc(cfg_hide( - not(valuable_no_atomic_cas), - not(valuable_no_atomic), - not(valuable_no_atomic_64) - )) -)] +#![cfg_attr(docsrs, feature(doc_cfg))] #[cfg(feature = "alloc")] extern crate alloc;