From f472a567e1d3e00a2ea021bf01b6c8e4296dd034 Mon Sep 17 00:00:00 2001 From: Roland Fredenhagen Date: Thu, 30 Jan 2025 22:53:49 +0100 Subject: [PATCH] skip(Clone) --- CHANGELOG.md | 3 ++ src/attr/item.rs | 2 +- src/attr/skip.rs | 25 +++++++++++-- src/data.rs | 2 +- src/error.rs | 6 +++ src/test/bound.rs | 16 ++++---- src/test/clone.rs | 54 +++++++++++++++++++++++++-- src/trait_/clone.rs | 30 ++++++++------- tests/skip/field_trait.rs | 14 ++++++- tests/skip/struct_trait.rs | 22 +++++++++-- tests/skip/variant_trait.rs | 27 ++++++++++++-- tests/ui/not-zeroize/item_skip.rs | 4 +- tests/ui/not-zeroize/item_skip.stderr | 6 +-- tests/ui/not-zeroize/skip.rs | 4 +- tests/ui/not-zeroize/skip.stderr | 6 +-- tests/ui/skip.rs | 3 ++ tests/ui/skip.stderr | 6 +++ tests/ui/zeroize/item_skip.rs | 4 +- tests/ui/zeroize/item_skip.stderr | 6 +-- tests/ui/zeroize/skip.rs | 4 +- tests/ui/zeroize/skip.stderr | 8 ++-- 21 files changed, 194 insertions(+), 58 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 24e14554..8c87f89d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Added +- Allow skipping fields for `Clone`, calling `Default::default()` instead. + **Note:** `Clone` is excluded from `#[derive_where(skip)]` to avoid this being a breaking change. ### Changed - Use the `Copy` implementation for `Clone` and the `Ord` implementation for diff --git a/src/attr/item.rs b/src/attr/item.rs index e0b6d03f..61b38154 100644 --- a/src/attr/item.rs +++ b/src/attr/item.rs @@ -256,7 +256,7 @@ impl DeriveWhere { pub fn any_skip(&self) -> bool { self.traits .iter() - .any(|trait_| SkipGroup::trait_supported(**trait_)) + .any(|trait_| SkipGroup::trait_supported_by_skip_all(**trait_)) } /// Create [`WhereClause`] for the given parameters. diff --git a/src/attr/skip.rs b/src/attr/skip.rs index e146d58a..c18a46bf 100644 --- a/src/attr/skip.rs +++ b/src/attr/skip.rs @@ -4,7 +4,7 @@ use std::default::Default; use syn::{spanned::Spanned, Meta, Path, Result}; -use crate::{util::MetaListExt, DeriveWhere, Error, Trait}; +use crate::{attr::DeriveTrait, util::MetaListExt, DeriveWhere, Error, Trait}; /// Stores what [`Trait`]s to skip this field or variant for. #[cfg_attr(test, derive(Debug))] @@ -101,6 +101,18 @@ impl Skip { if let Meta::Path(path) = nested_meta { let skip_group = SkipGroup::from_path(path)?; + if skip_group == SkipGroup::Clone + && derive_wheres.iter().any(|derive_where| { + derive_where + .traits + .iter() + .any(|trait_| trait_ == &DeriveTrait::Copy) + }) { + return Err(Error::unable_to_skip_clone_while_deriving_copy( + path.span(), + )); + } + // Don't allow to skip the same trait twice. if traits.contains(&skip_group) { return Err(Error::option_skip_duplicate( @@ -144,7 +156,7 @@ impl Skip { pub fn trait_skipped(&self, trait_: Trait) -> bool { match self { Skip::None => false, - Skip::All => SkipGroup::trait_supported(trait_), + Skip::All => SkipGroup::trait_supported_by_skip_all(trait_), Skip::Traits(skip_groups) => skip_groups .iter() .any(|skip_group| skip_group.traits().any(|this_trait| this_trait == trait_)), @@ -166,6 +178,8 @@ impl Skip { #[derive(Clone, Copy, Eq, PartialEq)] #[cfg_attr(test, derive(Debug))] pub enum SkipGroup { + /// [`Clone`]. + Clone, /// [`Debug`]. Debug, /// [`Eq`], [`Hash`], [`Ord`], [`PartialEq`] and [`PartialOrd`]. @@ -185,6 +199,7 @@ impl SkipGroup { use SkipGroup::*; match ident.to_string().as_str() { + "Clone" => Ok(Clone), "Debug" => Ok(Debug), "EqHashOrd" => Ok(EqHashOrd), "Hash" => Ok(Hash), @@ -202,6 +217,7 @@ impl SkipGroup { /// messages. const fn as_str(self) -> &'static str { match self { + Self::Clone => "Clone", Self::Debug => "Debug", Self::EqHashOrd => "EqHashOrd", Self::Hash => "Hash", @@ -213,6 +229,9 @@ impl SkipGroup { /// [`Trait`]s supported by this group. fn traits(self) -> impl Iterator { match self { + Self::Clone => [Some(Trait::Clone), None, None, None, None] + .into_iter() + .flatten(), Self::Debug => [Some(Trait::Debug), None, None, None, None] .into_iter() .flatten(), @@ -242,7 +261,7 @@ impl SkipGroup { } /// Returns `true` if [`Trait`] is supported by any group. - pub fn trait_supported(trait_: Trait) -> bool { + pub fn trait_supported_by_skip_all(trait_: Trait) -> bool { match trait_ { Trait::Clone | Trait::Copy | Trait::Default => false, Trait::Debug diff --git a/src/data.rs b/src/data.rs index e2f35536..4b54e187 100644 --- a/src/data.rs +++ b/src/data.rs @@ -311,7 +311,7 @@ impl<'a> Data<'a> { } /// Returns `true` if all fields are skipped with that [`Trait`]. - fn skip(&self, trait_: Trait) -> bool { + pub fn skip(&self, trait_: Trait) -> bool { self.skip_inner.trait_skipped(trait_) || match self.fields() { Either::Left(fields) => fields.skip(trait_), diff --git a/src/error.rs b/src/error.rs index 9557ac58..1b93e409 100644 --- a/src/error.rs +++ b/src/error.rs @@ -277,6 +277,11 @@ impl Error { ) } + /// Unsupported `skip(Clone)` while deriving copy. + pub fn unable_to_skip_clone_while_deriving_copy(skip_clone: Span) -> syn::Error { + syn::Error::new(skip_clone, "Cannot skip `Clone` while deriving `Copy`") + } + /// List of available [`Trait`](crate::Trait)s. fn trait_list() -> String { [ @@ -300,6 +305,7 @@ impl Error { /// List of available [`SkipGroup`](crate::SkipGroup)s. fn skip_group_list() -> String { [ + "Clone", "Debug", "EqHashOrd", "Hash", diff --git a/src/test/bound.rs b/src/test/bound.rs index 07ba6008..48268baa 100644 --- a/src/test/bound.rs +++ b/src/test/bound.rs @@ -18,7 +18,7 @@ fn bound() -> Result<()> { #[inline] fn clone(&self) -> Self { match self { - Test(ref __field_0, ref __field_1) => Test(::core::clone::Clone::clone(__field_0), ::core::clone::Clone::clone(__field_1)), + Test(ref __field_0, ref __field_1) => Test { 0: ::core::clone::Clone::clone(__field_0), 1: ::core::clone::Clone::clone(__field_1) }, } } } @@ -48,7 +48,7 @@ fn bound_multiple() -> Result<()> { #[inline] fn clone(&self) -> Self { match self { - Test(ref __field_0, ref __field_1) => Test(::core::clone::Clone::clone(__field_0), ::core::clone::Clone::clone(__field_1)), + Test(ref __field_0, ref __field_1) => Test{ 0: ::core::clone::Clone::clone(__field_0), 1: ::core::clone::Clone::clone(__field_1) }, } } } @@ -78,7 +78,7 @@ fn custom_bound() -> Result<()> { #[inline] fn clone(&self) -> Self { match self { - Test(ref __field_0) => Test(::core::clone::Clone::clone(__field_0)), + Test(ref __field_0) => Test { 0: ::core::clone::Clone::clone(__field_0) }, } } } @@ -103,7 +103,7 @@ fn where_() -> Result<()> { #[inline] fn clone(&self) -> Self { match self { - Test(ref __field_0, ref __field_1) => Test(::core::clone::Clone::clone(__field_0), ::core::clone::Clone::clone(__field_1)), + Test(ref __field_0, ref __field_1) => Test { 0: ::core::clone::Clone::clone(__field_0), 1: ::core::clone::Clone::clone(__field_1) }, } } } @@ -126,7 +126,7 @@ fn associated_type() -> Result<()> { #[inline] fn clone(&self) -> Self { match self { - Test(ref __field_0) => Test(::core::clone::Clone::clone(__field_0)), + Test(ref __field_0) => Test { 0: ::core::clone::Clone::clone(__field_0) }, } } } @@ -149,7 +149,7 @@ fn associated_type_custom_bound() -> Result<()> { #[inline] fn clone(&self) -> Self { match self { - Test(ref __field_0) => Test(::core::clone::Clone::clone(__field_0)), + Test(ref __field_0) => Test { 0: ::core::clone::Clone::clone(__field_0) }, } } } @@ -172,7 +172,7 @@ fn check_trait_bounds() -> Result<()> { #[inline] fn clone(&self) -> Self { match self { - Test(ref __field_0, ref __field_1) => Test(::core::clone::Clone::clone(__field_0), ::core::clone::Clone::clone(__field_1)), + Test(ref __field_0, ref __field_1) => Test { 0: ::core::clone::Clone::clone(__field_0), 1: ::core::clone::Clone::clone(__field_1) }, } } } @@ -308,7 +308,7 @@ fn check_multiple_trait_bounds() -> Result<()> { #[inline] fn clone(&self) -> Self { match self { - Test(ref __field_0, ref __field_1) => Test(::core::clone::Clone::clone(__field_0), ::core::clone::Clone::clone(__field_1)), + Test(ref __field_0, ref __field_1) => Test { 0: ::core::clone::Clone::clone(__field_0), 1: ::core::clone::Clone::clone(__field_1) }, } } } diff --git a/src/test/clone.rs b/src/test/clone.rs index fdaafdd4..4a8bb0b2 100644 --- a/src/test/clone.rs +++ b/src/test/clone.rs @@ -26,6 +26,54 @@ fn struct_() -> Result<()> { ) } +#[test] +fn skip_inner() -> Result<()> { + test_derive( + quote! { + #[derive_where(Clone)] + #[derive_where(skip_inner(Clone))] + struct Test { + field: std::marker::PhantomData, + } + }, + quote! { + #[automatically_derived] + impl ::core::clone::Clone for Test { + #[inline] + fn clone(&self) -> Self { + match self { + Test { field: ref __field_field } => Test { field: ::core::default::Default::default() }, + } + } + } + }, + ) +} + +#[test] +fn skip_field() -> Result<()> { + test_derive( + quote! { + #[derive_where(Clone)] + struct Test { + #[derive_where(skip(Clone))] + field: std::marker::PhantomData, + } + }, + quote! { + #[automatically_derived] + impl ::core::clone::Clone for Test { + #[inline] + fn clone(&self) -> Self { + match self { + Test { field: ref __field_field } => Test { field: ::core::default::Default::default() }, + } + } + } + }, + ) +} + #[test] fn tuple() -> Result<()> { test_derive( @@ -39,7 +87,7 @@ fn tuple() -> Result<()> { #[inline] fn clone(&self) -> Self { match self { - Test(ref __field_0) => Test(::core::clone::Clone::clone(__field_0)), + Test(ref __field_0) => Test { 0: ::core::clone::Clone::clone(__field_0) }, } } } @@ -68,8 +116,8 @@ fn enum_() -> Result<()> { match self { Test::A { field: ref __field_field } => Test::A { field: ::core::clone::Clone::clone(__field_field) }, Test::B { } => Test::B { }, - Test::C(ref __field_0) => Test::C(::core::clone::Clone::clone(__field_0)), - Test::D() => Test::D(), + Test::C(ref __field_0) => Test::C { 0: ::core::clone::Clone::clone(__field_0) }, + Test::D() => Test::D { }, Test::E => Test::E, } } diff --git a/src/trait_/clone.rs b/src/trait_/clone.rs index dd08a33b..94592b33 100644 --- a/src/trait_/clone.rs +++ b/src/trait_/clone.rs @@ -5,7 +5,8 @@ use quote::quote; use syn::{TraitBound, TraitBoundModifier, TypeParamBound}; use crate::{ - Data, DataType, DeriveTrait, DeriveWhere, Item, SimpleType, SplitGenerics, Trait, TraitImpl, + data::Field, Data, DataType, DeriveTrait, DeriveWhere, Item, SimpleType, SplitGenerics, Trait, + TraitImpl, }; /// Dummy-struct implement [`Trait`] for [`Clone`](trait@std::clone::Clone). @@ -99,25 +100,26 @@ impl TraitImpl for Clone { } match data.simple_type() { - SimpleType::Struct(fields) => { + SimpleType::Struct(fields) | SimpleType::Tuple(fields) => { let self_pattern = &fields.self_pattern; let item_path = &data.path; - let self_ident = data.iter_self_ident(**trait_); - let fields = data.iter_field_ident(**trait_); let trait_path = trait_.path(); + let default_path = DeriveTrait::Default.path(); - quote! { - #self_pattern => #item_path { #(#fields: #trait_path::clone(#self_ident)),* }, - } - } - SimpleType::Tuple(fields) => { - let self_pattern = &fields.self_pattern; - let item_path = &data.path; - let self_ident = data.iter_self_ident(**trait_); - let trait_path = trait_.path(); + let fields = fields.fields.iter().map( + |field @ Field { + self_ident, member, .. + }| { + if field.skip(Trait::Clone) || data.skip(Trait::Clone) { + quote!(#member: #default_path::default()) + } else { + quote!(#member: #trait_path::clone(#self_ident)) + } + }, + ); quote! { - #self_pattern => #item_path(#(#trait_path::clone(#self_ident)),*), + #self_pattern => #item_path { #(#fields),* }, } } SimpleType::Unit(pattern) => { diff --git a/tests/skip/field_trait.rs b/tests/skip/field_trait.rs index 567b4bf9..7f98a1ae 100644 --- a/tests/skip/field_trait.rs +++ b/tests/skip/field_trait.rs @@ -4,7 +4,7 @@ use std::cmp::Ordering; use derive_where::derive_where; use crate::util::{ - self, AssertDebug, AssertHash, AssertOrd, AssertPartialEq, AssertPartialOrd, Wrapper, + self, AssertClone, AssertDebug, AssertHash, AssertOrd, AssertPartialEq, AssertPartialOrd, Wrapper }; #[test] @@ -19,6 +19,18 @@ fn debug() { assert_eq!(format!("{:?}", test_1), "Test"); } +#[test] +fn clone() { + #[derive_where(Clone)] + struct Test(#[derive_where(skip(Clone))] Wrapper); + + let test_1 = Test(42.into()); + + let _ = AssertClone(&test_1); + + assert_eq!(test_1.clone().0, 0) +} + #[test] fn hash() { #[derive_where(Hash)] diff --git a/tests/skip/struct_trait.rs b/tests/skip/struct_trait.rs index e9df4a71..c4ea0aba 100644 --- a/tests/skip/struct_trait.rs +++ b/tests/skip/struct_trait.rs @@ -4,7 +4,7 @@ use std::cmp::Ordering; use derive_where::derive_where; use crate::util::{ - self, AssertDebug, AssertHash, AssertOrd, AssertPartialEq, AssertPartialOrd, Wrapper, + self, AssertClone, AssertDebug, AssertHash, AssertOrd, AssertPartialEq, AssertPartialOrd, Wrapper }; #[test] @@ -20,6 +20,19 @@ fn debug() { assert_eq!(format!("{:?}", test_1), "Test"); } +#[test] +fn clone() { + #[derive_where(Clone)] + #[derive_where(skip_inner(Clone))] + struct Test(Wrapper); + + let test_1 = Test(42.into()); + + let _ = AssertClone(&test_1); + + assert_eq!(test_1.clone().0, 0); +} + #[test] fn hash() { #[derive_where(Hash)] @@ -67,8 +80,8 @@ fn ord() { #[test] fn all() { - #[derive_where(Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] - #[derive_where(skip_inner(Debug, EqHashOrd))] + #[derive_where(Debug, Eq, Hash, Ord, PartialEq, PartialOrd, Clone)] + #[derive_where(skip_inner(Debug, EqHashOrd, Clone))] struct Test(Wrapper); let test_1 = Test(42.into()); @@ -76,6 +89,7 @@ fn all() { let test_le = Test(41.into()); let test_ge = Test(43.into()); + let _ = AssertClone(&test_1); let _ = AssertDebug(&test_1); let _ = AssertHash(&test_1); let _ = AssertOrd(&test_1); @@ -84,6 +98,8 @@ fn all() { assert_eq!(format!("{:?}", test_1), "Test"); + assert_eq!(test_1.clone().0, 0); + util::hash_eq(&test_1, &test_2); util::hash_eq(&test_1, &test_ge); diff --git a/tests/skip/variant_trait.rs b/tests/skip/variant_trait.rs index 83ab7c36..9fd92fa1 100644 --- a/tests/skip/variant_trait.rs +++ b/tests/skip/variant_trait.rs @@ -2,9 +2,11 @@ use std::cmp::Ordering; use derive_where::derive_where; +use pretty_assertions::assert_eq; use crate::util::{ - self, AssertDebug, AssertHash, AssertOrd, AssertPartialEq, AssertPartialOrd, Wrapper, + self, AssertClone, AssertDebug, AssertHash, AssertOrd, AssertPartialEq, AssertPartialOrd, + Wrapper, }; #[test] @@ -22,6 +24,22 @@ fn debug() { assert_eq!(format!("{:?}", test_1), "A"); } +#[test] +fn clone() { + #[derive_where(Clone)] + enum Test { + #[derive_where(skip_inner(Clone))] + A(Wrapper), + } + + let test_1 = Test::A(42.into()); + + let _ = AssertClone(&test_1); + + let Test::A(cloned) = test_1.clone(); + assert_eq!(cloned, 0); +} + #[test] fn hash() { #[derive_where(Hash)] @@ -73,9 +91,9 @@ fn ord() { #[test] fn all() { - #[derive_where(Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] + #[derive_where(Debug, Eq, Hash, Ord, PartialEq, PartialOrd, Clone)] enum Test { - #[derive_where(skip_inner(Debug, EqHashOrd))] + #[derive_where(skip_inner(Debug, EqHashOrd, Clone))] A(Wrapper), } @@ -85,6 +103,7 @@ fn all() { let test_ge = Test::A(43.into()); let _ = AssertDebug(&test_1); + let _ = AssertClone(&test_1); let _ = AssertHash(&test_1); let _ = AssertOrd(&test_1); let _ = AssertPartialEq(&test_1); @@ -92,6 +111,8 @@ fn all() { assert_eq!(format!("{:?}", test_1), "A"); + assert_eq!(test_1.clone(), Test::A(0.into())); + util::hash_eq(&test_1, &test_2); util::hash_eq(&test_1, &test_ge); diff --git a/tests/ui/not-zeroize/item_skip.rs b/tests/ui/not-zeroize/item_skip.rs index aebf8031..3a9464cb 100644 --- a/tests/ui/not-zeroize/item_skip.rs +++ b/tests/ui/not-zeroize/item_skip.rs @@ -2,8 +2,8 @@ use std::marker::PhantomData; use derive_where::derive_where; -#[derive_where(Clone; T)] -#[derive_where(skip_inner(Clone))] +#[derive_where(Copy; T)] +#[derive_where(skip_inner(Copy))] struct UnsupportedTrait(PhantomData); fn main() {} diff --git a/tests/ui/not-zeroize/item_skip.stderr b/tests/ui/not-zeroize/item_skip.stderr index f2faddbb..de66a5e7 100644 --- a/tests/ui/not-zeroize/item_skip.stderr +++ b/tests/ui/not-zeroize/item_skip.stderr @@ -1,5 +1,5 @@ -error: unsupported skip group, expected one of Debug, EqHashOrd, Hash +error: unsupported skip group, expected one of Clone, Debug, EqHashOrd, Hash --> tests/ui/not-zeroize/item_skip.rs:6:27 | -6 | #[derive_where(skip_inner(Clone))] - | ^^^^^ +6 | #[derive_where(skip_inner(Copy))] + | ^^^^ diff --git a/tests/ui/not-zeroize/skip.rs b/tests/ui/not-zeroize/skip.rs index c4e6a326..f8f861df 100644 --- a/tests/ui/not-zeroize/skip.rs +++ b/tests/ui/not-zeroize/skip.rs @@ -2,7 +2,7 @@ use std::marker::PhantomData; use derive_where::derive_where; -#[derive_where(Clone; T)] -struct UnsupportedTrait(#[derive_where(skip(Clone))] PhantomData); +#[derive_where(Copy; T)] +struct UnsupportedTrait(#[derive_where(skip(Copy))] PhantomData); fn main() {} diff --git a/tests/ui/not-zeroize/skip.stderr b/tests/ui/not-zeroize/skip.stderr index 99105e49..44e02135 100644 --- a/tests/ui/not-zeroize/skip.stderr +++ b/tests/ui/not-zeroize/skip.stderr @@ -1,5 +1,5 @@ -error: unsupported skip group, expected one of Debug, EqHashOrd, Hash +error: unsupported skip group, expected one of Clone, Debug, EqHashOrd, Hash --> tests/ui/not-zeroize/skip.rs:6:48 | -6 | struct UnsupportedTrait(#[derive_where(skip(Clone))] PhantomData); - | ^^^^^ +6 | struct UnsupportedTrait(#[derive_where(skip(Copy))] PhantomData); + | ^^^^ diff --git a/tests/ui/skip.rs b/tests/ui/skip.rs index 40a7742c..838b4a95 100644 --- a/tests/ui/skip.rs +++ b/tests/ui/skip.rs @@ -45,4 +45,7 @@ struct DuplicateTraitSeparate( #[derive_where(Clone; T)] struct MissingDeriveTrait(#[derive_where(skip(Debug))] PhantomData); +#[derive_where(Clone, Copy)] +struct SkipCloneWhileCopy(#[derive_where(skip(Clone))] PhantomData); + fn main() {} diff --git a/tests/ui/skip.stderr b/tests/ui/skip.stderr index eadeee49..d1191b25 100644 --- a/tests/ui/skip.stderr +++ b/tests/ui/skip.stderr @@ -51,3 +51,9 @@ error: trait to be skipped isn't being implemented | 46 | struct MissingDeriveTrait(#[derive_where(skip(Debug))] PhantomData); | ^^^^^ + +error: Cannot skip `Clone` while deriving `Copy` + --> tests/ui/skip.rs:49:50 + | +49 | struct SkipCloneWhileCopy(#[derive_where(skip(Clone))] PhantomData); + | ^^^^^ diff --git a/tests/ui/zeroize/item_skip.rs b/tests/ui/zeroize/item_skip.rs index aebf8031..3a9464cb 100644 --- a/tests/ui/zeroize/item_skip.rs +++ b/tests/ui/zeroize/item_skip.rs @@ -2,8 +2,8 @@ use std::marker::PhantomData; use derive_where::derive_where; -#[derive_where(Clone; T)] -#[derive_where(skip_inner(Clone))] +#[derive_where(Copy; T)] +#[derive_where(skip_inner(Copy))] struct UnsupportedTrait(PhantomData); fn main() {} diff --git a/tests/ui/zeroize/item_skip.stderr b/tests/ui/zeroize/item_skip.stderr index 2723f957..9f8ec6f8 100644 --- a/tests/ui/zeroize/item_skip.stderr +++ b/tests/ui/zeroize/item_skip.stderr @@ -1,5 +1,5 @@ -error: unsupported skip group, expected one of Debug, EqHashOrd, Hash, Zeroize +error: unsupported skip group, expected one of Clone, Debug, EqHashOrd, Hash, Zeroize --> tests/ui/zeroize/item_skip.rs:6:27 | -6 | #[derive_where(skip_inner(Clone))] - | ^^^^^ +6 | #[derive_where(skip_inner(Copy))] + | ^^^^ diff --git a/tests/ui/zeroize/skip.rs b/tests/ui/zeroize/skip.rs index c4e6a326..6f866f0d 100644 --- a/tests/ui/zeroize/skip.rs +++ b/tests/ui/zeroize/skip.rs @@ -2,7 +2,7 @@ use std::marker::PhantomData; use derive_where::derive_where; -#[derive_where(Clone; T)] -struct UnsupportedTrait(#[derive_where(skip(Clone))] PhantomData); +#[derive_where(Skip; T)] +struct UnsupportedTrait(#[derive_where(skip(Skip))] PhantomData); fn main() {} diff --git a/tests/ui/zeroize/skip.stderr b/tests/ui/zeroize/skip.stderr index 4dddf78c..acc20bab 100644 --- a/tests/ui/zeroize/skip.stderr +++ b/tests/ui/zeroize/skip.stderr @@ -1,5 +1,5 @@ -error: unsupported skip group, expected one of Debug, EqHashOrd, Hash, Zeroize - --> tests/ui/zeroize/skip.rs:6:48 +error: unsupported trait, expected one of Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd, Zeroize, ZeroizeOnDrop + --> tests/ui/zeroize/skip.rs:5:16 | -6 | struct UnsupportedTrait(#[derive_where(skip(Clone))] PhantomData); - | ^^^^^ +5 | #[derive_where(Skip; T)] + | ^^^^