Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trying to clone references to non-cloneable types gives a confusing error messages. #52095

Closed
moxian opened this issue Jul 6, 2018 · 3 comments
Labels
A-diagnostics Area: Messages for errors, warnings, and lints

Comments

@moxian
Copy link
Contributor

moxian commented Jul 6, 2018

When trying to compile this piece of code (playground link):

#[derive(Clone)]
struct Wrapper<T>
{
    inner: T,
}

fn dewrap<T>(d: &Wrapper<T>) -> Wrapper<T>
//where T: Clone
{
    d.clone()
}

I get the following error message:

error[E0308]: mismatched types
  --> src/main.rs:11:4
   |
8  | fn dewrap<T>(d: &Wrapper<T>) -> Wrapper<T>
   |                                 ---------- expected `Wrapper<T>` because of return type
...
11 |    d.clone()
   |    ^^^^^^^^^^^ expected struct `Wrapper`, found &Wrapper<T>
   |
   = note: expected type `Wrapper<T>`
              found type `&Wrapper<T>`

which is super weird, because the signature of .clone() is clone(&T)->T.

I'm not fully certain what exactly is happening here (I guess, d is getting auto-referenced, and the function body is equivalent to (&d).clone()), but regardless the error message is super confusing.

I would appreciate if some kind of did you mean to add trait bounds T: Clone? diagnostic was added.

Relatedly (but may be more suitable for a separate bugreport?), the struct declaration has #[derive(Clone)] but the derive fails silently, since T does not have : Clone bounds. It still may be what the author intended (the derive will work when the struct is instantiated with a cloneable type), but I'm afraid it usually isn't.

Also relatedly: clippy does catch the error:

error: using `clone` on a double-reference; this will copy the reference instead of cloning the inner type
  --> src/main.rs:11:4
   |
11 |    (d.clone())
   |    ^^^^^^^^^^^
   |
   = note: #[deny(clone_double_ref)] on by default
   = help: for further information visit https://rust-lang-nursery.github.io/rust-clippy/v0.0.211/index.html#clone_double_ref
help: try dereferencing it
   |
11 |    &(*d).clone()
   |
help: or try being explicit about what type to clone
   |
11 |    &Wrapper<T>::clone(d)

Unfortunately this is displayed only after the error is pseudo-fixed by declaring the function return type to be &Wrapper<T>, and not displayed at all when fixed for good by adding the : Clone trait bound.

It might be useful to uplift the diagnostics to rustc here (but I have zero understanding of the process or feasibility of this).

@csmoe csmoe added the A-diagnostics Area: Messages for errors, warnings, and lints label Jul 6, 2018
@abonander
Copy link
Contributor

This seems like it might be a regression. Maybe a bisect is in order?

@abonander
Copy link
Contributor

abonander commented Aug 17, 2018

Nevermind, this has been an issue for a while I guess: #34896, #48677

@moxian
Copy link
Contributor Author

moxian commented May 17, 2019

Closing in favour of #34896

@moxian moxian closed this as completed May 17, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints
Projects
None yet
Development

No branches or pull requests

3 participants