Skip to content

Clone suggestion appears inconsistently #112857

Closed
@strottos

Description

@strottos

Code

fn f<T>(a: &T) -> T {
    let ret = a.clone();
    ret
}

Current output

error[E0308]: mismatched types
 --> ./test.rs:3:5
  |
1 | fn f<T>(a: &T) -> T {
  |      -            - expected `T` because of return type
  |      |
  |      this type parameter
2 |     let ret = a.clone();
3 |     ret
  |     ^^^ expected type parameter `T`, found `&T`
  |
  = note: expected type parameter `T`
                  found reference `&T`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0308`.

Desired output

error[E0308]: mismatched types
 --> ./test.rs:3:5
  |
1 | fn f<T>(a: &T) -> T {
  |      -            - expected `T` because of return type
  |      |
  |      this type parameter
2 |     let ret = a.clone();
3 |     ret
  |     ^^^ expected type parameter `T`, found `&T`
  |
  = note: expected type parameter `T`
                  found reference `&T`
note: `T` does not implement `Clone`, so `&T` was cloned instead
 --> ./test.rs:2:5
  |
2 |     let ret = a.clone();
  |               ^
help: consider restricting type parameter `T`
  |
1 | fn f<T: Clone>(a: &T) -> T {
  |       +++++++

error: aborting due to previous error

For more information about this error, try `rustc --explain E0308`.

Rationale and extra context

This program gives the right hint:

fn f<T>(a: &T) -> T {
    a.clone()
}

Similarly we have the following that gives the hint:

fn f<T>(a: &T) -> T {
    let ret: T = a.clone();
    ret
}

Not the end of the world certainly but the diagnostic is really helpful and it would be nice if we could get the first one to output the issue too.

I think (having gone through the code a bit, though I'm new to this) that &a is being cloned rather than a as a doesn't necessarily implement Clone and then on a line 3 a type mismatch is found on a line that doesn't specify clone. So when it does the not_type_is_not_clone check in the rustc_hir_typeck crate it's only checking ret and it doesn't see that it comes from a clone attempt on the wrong type.

Other cases

No response

Anything else?

No response

Metadata

Metadata

Assignees

Labels

A-diagnosticsArea: Messages for errors, warnings, and lintsT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions