Skip to content

Commit

Permalink
Fix wrong usage of Copy in Clone when bounds are present (#87)
Browse files Browse the repository at this point in the history
  • Loading branch information
daxpedda authored Dec 4, 2023
1 parent b7e149d commit 46306f2
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 7 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file.
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]

### Fixed
- Use the `Copy` implementation for `Clone` only if no bounds are present.

## [1.2.5] - 2023-09-03

### Changed
Expand Down
8 changes: 6 additions & 2 deletions src/test/bound.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,9 @@ fn check_trait_bounds() -> Result<()> {
{
#[inline]
fn clone(&self) -> Self {
*self
match self {
Test(ref __field_0, ref __field_1) => Test(::core::clone::Clone::clone(__field_0), ::core::clone::Clone::clone(__field_1)),
}
}
}

Expand Down Expand Up @@ -277,7 +279,9 @@ fn check_multiple_trait_bounds() -> Result<()> {
{
#[inline]
fn clone(&self) -> Self {
*self
match self {
Test(ref __field_0, ref __field_1) => Test(::core::clone::Clone::clone(__field_0), ::core::clone::Clone::clone(__field_1)),
}
}
}

Expand Down
8 changes: 4 additions & 4 deletions src/trait_/clone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,15 @@ impl TraitImpl for Clone {

fn build_signature(
&self,
_any_bound: bool,
any_bound: bool,
item: &Item,
_generics: &SplitGenerics<'_>,
traits: &[DeriveTrait],
_trait_: &DeriveTrait,
body: &TokenStream,
) -> TokenStream {
// Special implementation for items also implementing `Copy`.
if traits.iter().any(|trait_| trait_ == Trait::Copy) {
if !any_bound && traits.iter().any(|trait_| trait_ == Trait::Copy) {
return quote! {
#[inline]
fn clone(&self) -> Self { *self }
Expand Down Expand Up @@ -85,12 +85,12 @@ impl TraitImpl for Clone {

fn build_body(
&self,
_any_bound: bool,
any_bound: bool,
traits: &[DeriveTrait],
trait_: &DeriveTrait,
data: &Data,
) -> TokenStream {
if traits.iter().any(|trait_| trait_ == Trait::Copy) {
if !any_bound && traits.iter().any(|trait_| trait_ == Trait::Copy) {
return TokenStream::new();
}

Expand Down
17 changes: 16 additions & 1 deletion tests/bound.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,22 @@ use std::marker::PhantomData;

use derive_where::derive_where;

use self::util::AssertClone;
use self::util::{AssertClone, AssertCopy};

#[test]
fn bound() {
#[derive_where(Clone, Copy; T)]
struct Test<T, U>(T, std::marker::PhantomData<U>);

let test_1 = Test(42, PhantomData::<()>);

let _ = AssertClone(&test_1);
let _ = AssertCopy(&test_1);

#[allow(clippy::clone_on_copy)]
let test_clone = test_1.clone();
assert_eq!(test_clone.0, 42);
}

#[test]
fn custom_generic() {
Expand Down

0 comments on commit 46306f2

Please sign in to comment.