Skip to content

Really confusing error when clone falls back to &T instance #54377

Closed
@RalfJung

Description

@RalfJung

Consider the following code:

trait Foo {
    type Assoc;
}

#[derive(Clone)]
struct Bar<F: Foo>(F::Assoc);

fn try_clone<F: Foo>(x: &Bar<F>) -> Bar<F>
    where F::Assoc: Clone
{
    x.clone()
}

This fails saying

error[E0308]: mismatched types
  --> src/lib.rs:11:5
   |
8  | fn try_clone<F: Foo>(x: &Bar<F>) -> Bar<F>
   |                                     ------ expected `Bar<F>` because of return type
...
11 |     x.clone()
   |     ^^^^^^^^^ expected struct `Bar`, found &Bar<F>
   |
   = note: expected type `Bar<F>`
              found type `&Bar<F>`

error: aborting due to previous error

I just stared at this for at least 5 minutes wondering how in the world clone could fail to return an owned copy... until I realized that what really happens is that it does (&x).clone() instead of Bar<F>::clone(x) because the latter fails to satisfy all trait constraints.

Might be worth having a specialized diagnostic for when clone and auto-(de)ref come together? Or more general, for when auto-(de)ref does something, and then fails, it should indicate somehow that auto-(de)ref happened, and maybe remark that some other possibilities were skipped because some bounds were not satisfied.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lints

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions