Skip to content

Add Clone and Copy derives#533

Open
fredszaq wants to merge 13 commits into
JelteF:masterfrom
fredszaq:clone_and_copy_derive
Open

Add Clone and Copy derives#533
fredszaq wants to merge 13 commits into
JelteF:masterfrom
fredszaq:clone_and_copy_derive

Conversation

@fredszaq
Copy link
Copy Markdown
Contributor

@fredszaq fredszaq commented Jan 9, 2026

Resolves #439

Synopsis

This adds 2 new derives for Clone and Copy. Those won't put any additionnal contraints on generic types by default, but provide #[clone(bound(...))] and #[copy(bound(...))] attributes if you need a fine tune the bounds

Solution

I moved the Bounds attribute from the fmt module to utils and reused it for both Derives

Checklist

  • Documentation is updated (if required)
  • Tests are added/updated (if required)
  • CHANGELOG entry is added (if required)

@fredszaq fredszaq changed the title Clone and copy derive Add Clone and Copy derives Jan 9, 2026
@tyranron tyranron assigned tyranron and fredszaq and unassigned tyranron Jan 9, 2026
@tyranron tyranron added enhancement k::api Related to API (application interface) labels Jan 9, 2026
@tyranron tyranron added this to the next milestone Jan 9, 2026
@fredszaq fredszaq mentioned this pull request Jan 9, 2026
3 tasks
@fredszaq
Copy link
Copy Markdown
Contributor Author

merged master into this to address the conflict in cargo.toml

Comment thread impl/src/utils.rs Outdated

impl Bounds {
/// Errors in case legacy syntax is encountered: `bound = "..."`.
fn check_legacy_fmt(input: ParseStream<'_>) -> syn::Result<()> {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fredszaq I think after two major releases and few years passed, we may remove checks for legacy syntax.

Copy link
Copy Markdown
Contributor Author

@fredszaq fredszaq May 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed that ! I updated the compile fail tests to the new error message, should I just remove them ?

Comment thread impl/src/copy.rs Outdated
let clause = clause.item.0;
quote! { where #clause }
})
.or(where_clause.map(ToTokens::to_token_stream));
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fredszaq see... there are two possible modes of applying custom where bounds:

  1. Replacing: just use the provided ones (like here).
  2. Additive: intermix the provided ones together with inferred ones.

For now, some macros use the first one, other the second one, reusing the same syntax for it. I don't like this situation. It's hard to remember or understand the concrete behavior for the concrete macro and requires either peeking into the macro expansion or reading the documentation every time.

I think these two modes should be clearly separated on the syntax level. For example:

#[bound(T: Trait)] // additive mode
#[bound(overwrite(T: Trait))] // replacing mode

I'm not sure of the concrete syntax, though, and would appreciate the suggestions.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tyranron I changed the code to actually extend the where clause we get from the struct definition instead of completely replacing it, this actually makes way more sense.

This makes Copy and Clone derives behave more in the additive fashion, even though they don't do clever type inference like the Display-family ones.

Do you think that is enough to have both uses cases use the same syntax ? (I didn't see other usages of where bounds in the lib)

If we wan't to actually support both types of bounds settings I guess the ideal would be

#[extra_bound(T: Trait)] // additive mode
#[bound(T: Trait)] // replacing mode

but this means breaking the behavior for every user of the feature, so probably not advised, maybe

#[exact_bound(T: Trait)

for the replacing mode could be an option ? it feels a bit clunky thought

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement k::api Related to API (application interface)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add support for deriving Clone/Copy and other standard traits without generic type parameter transitiveness

2 participants