Skip to content

Commit 46306f2

Browse files
authored
Fix wrong usage of Copy in Clone when bounds are present (#87)
1 parent b7e149d commit 46306f2

File tree

4 files changed

+31
-7
lines changed

4 files changed

+31
-7
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [Unreleased]
9+
10+
### Fixed
11+
- Use the `Copy` implementation for `Clone` only if no bounds are present.
12+
813
## [1.2.5] - 2023-09-03
914

1015
### Changed

src/test/bound.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,9 @@ fn check_trait_bounds() -> Result<()> {
152152
{
153153
#[inline]
154154
fn clone(&self) -> Self {
155-
*self
155+
match self {
156+
Test(ref __field_0, ref __field_1) => Test(::core::clone::Clone::clone(__field_0), ::core::clone::Clone::clone(__field_1)),
157+
}
156158
}
157159
}
158160

@@ -277,7 +279,9 @@ fn check_multiple_trait_bounds() -> Result<()> {
277279
{
278280
#[inline]
279281
fn clone(&self) -> Self {
280-
*self
282+
match self {
283+
Test(ref __field_0, ref __field_1) => Test(::core::clone::Clone::clone(__field_0), ::core::clone::Clone::clone(__field_1)),
284+
}
281285
}
282286
}
283287

src/trait_/clone.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,15 +42,15 @@ impl TraitImpl for Clone {
4242

4343
fn build_signature(
4444
&self,
45-
_any_bound: bool,
45+
any_bound: bool,
4646
item: &Item,
4747
_generics: &SplitGenerics<'_>,
4848
traits: &[DeriveTrait],
4949
_trait_: &DeriveTrait,
5050
body: &TokenStream,
5151
) -> TokenStream {
5252
// Special implementation for items also implementing `Copy`.
53-
if traits.iter().any(|trait_| trait_ == Trait::Copy) {
53+
if !any_bound && traits.iter().any(|trait_| trait_ == Trait::Copy) {
5454
return quote! {
5555
#[inline]
5656
fn clone(&self) -> Self { *self }
@@ -85,12 +85,12 @@ impl TraitImpl for Clone {
8585

8686
fn build_body(
8787
&self,
88-
_any_bound: bool,
88+
any_bound: bool,
8989
traits: &[DeriveTrait],
9090
trait_: &DeriveTrait,
9191
data: &Data,
9292
) -> TokenStream {
93-
if traits.iter().any(|trait_| trait_ == Trait::Copy) {
93+
if !any_bound && traits.iter().any(|trait_| trait_ == Trait::Copy) {
9494
return TokenStream::new();
9595
}
9696

tests/bound.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,22 @@ use std::marker::PhantomData;
44

55
use derive_where::derive_where;
66

7-
use self::util::AssertClone;
7+
use self::util::{AssertClone, AssertCopy};
8+
9+
#[test]
10+
fn bound() {
11+
#[derive_where(Clone, Copy; T)]
12+
struct Test<T, U>(T, std::marker::PhantomData<U>);
13+
14+
let test_1 = Test(42, PhantomData::<()>);
15+
16+
let _ = AssertClone(&test_1);
17+
let _ = AssertCopy(&test_1);
18+
19+
#[allow(clippy::clone_on_copy)]
20+
let test_clone = test_1.clone();
21+
assert_eq!(test_clone.0, 42);
22+
}
823

924
#[test]
1025
fn custom_generic() {

0 commit comments

Comments
 (0)