Skip to content

non-Clone type, with Clone associated type, as type param leads to confusing behavior in #[derive(Clone)] #124300

Closed as not planned
@chebbyChefNEQ

Description

@chebbyChefNEQ

I tried this code:

trait NotClone {
    type AssocClonable: Clone;
}

struct NotCloneImpl;

impl NotClone for NotCloneImpl {
    type AssocClonable = i32;
}

#[derive(Clone)]
struct ShouldBeClone<T: NotClone>
{
    _value: T::AssocClonable
}

fn main() {
    // Compiles with no error or warnings -- minus unused variable
    let a = ShouldBeClone::<NotCloneImpl> { _value: 1 };
    
    // let clone_a: ShouldBeClone<NotCloneImpl> = (&a).clone();
    // let clone_a: ShouldBeClone<NotCloneImpl> = a.clone();
}

the the two clones are uncommented
fails with

   Compiling bugs v0.1.0 (/Users/robmeng/workspace/bugs)
error[E0599]: the method `clone` exists for struct `ShouldBeClone<NotCloneImpl>`, but its trait bounds were not satisfied
  --> main.rs:19:50
   |
5  | struct NotCloneImpl;
   | ------------------- doesn't satisfy `NotCloneImpl: Clone`
...
12 | struct ShouldBeClone<T: NotClone>
   | --------------------------------- method `clone` not found for this struct because it doesn't satisfy `ShouldBeClone<NotCloneImpl>: Clone`
...
19 |     let clone_a: ShouldBeClone<NotCloneImpl> = a.clone();
   |                                                  ^^^^^ method cannot be called on `ShouldBeClone<NotCloneImpl>` due to unsatisfied trait bounds
   |
note: trait bound `NotCloneImpl: Clone` was not satisfied
  --> main.rs:11:10
   |
11 | #[derive(Clone)]
   |          ^^^^^ unsatisfied trait bound introduced in this `derive` macro
   = help: items from traits can only be used if the trait is implemented and in scope
   = note: the following trait defines an item `clone`, perhaps you need to implement it:
           candidate #1: `Clone`
help: consider annotating `NotCloneImpl` with `#[derive(Clone)]`
   |
5  + #[derive(Clone)]
6  | struct NotCloneImpl;
   |

error[E0308]: mismatched types
  --> main.rs:20:48
   |
20 |     let clone_a: ShouldBeClone<NotCloneImpl> = (&a).clone();
   |                  ---------------------------   ^^^^^^^^^^^^ expected `ShouldBeClone<NotCloneImpl>`, found `&ShouldBeClone<NotCloneImpl>`
   |                  |
   |                  expected due to this
   |
   = note: expected struct `ShouldBeClone<_>`
           found reference `&ShouldBeClone<_>`
note: `ShouldBeClone<NotCloneImpl>` does not implement `Clone`, so `&ShouldBeClone<NotCloneImpl>` was cloned instead
  --> main.rs:20:48
   |
20 |     let clone_a: ShouldBeClone<NotCloneImpl> = (&a).clone();
   |                                                ^^^^
   = help: `Clone` is not implemented because the trait bound `NotCloneImpl: Clone` is not satisfied
help: consider annotating `NotCloneImpl` with `#[derive(Clone)]`
   |
5  + #[derive(Clone)]
6  | struct NotCloneImpl;
   |
help: consider annotating `ShouldBeClone<NotCloneImpl>` with `#[derive(Clone)]`
   |
12 + #[derive(Clone)]
13 | struct ShouldBeClone<T: NotClone>
   |

Instead, this happened:
either

  • error that ShouldBeClone::<NotCloneImpl> can not be derive Clone because NotCloneImpl is not Clone
  • handle the case where the struct attribute depends on NotCloneImpl::AssociatedCloneableType

Meta

rustc --version --verbose:

rustc 1.77.2 (25ef9e3d8 2024-04-09)
binary: rustc
commit-hash: 25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04
commit-date: 2024-04-09
host: aarch64-apple-darwin
release: 1.77.2
LLVM version: 17.0.6

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions