-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Diagnostics for cloning references are terrible #34896
Comments
Interesting. This does seem like it would require some pretty special-case code to achieve, but I agree it'd be a nice case to capture. |
A relatively easy way to catch most instances of this is to
This will miss things, but I think the majority of such bugs will be due to this. As it stands this feels like an incredibly easy case to hit (we've all forgotten to decorate structs). |
CC #34629 |
As reported in #60875: use std::collections::HashMap;
#[derive(Clone, Debug)]
struct Foo;
#[derive(Debug)]
struct Bar;
type H = HashMap<String, Vec<(Foo, Bar)>>;
fn wat(h: &H) -> H {
let h: H = h.clone();
h
}
fn main() {
let h = H::new();
println!("{:?}", wat(&h));
} This reports:
|
Current output is even worse for the original report:
The last comment's code is marginally different:
|
Current output:
The last case should suggest constraining Edit: that was easier than I thought (we already had the suggestion machinery): |
…-errors Suggest constraining type parameter with `Clone` Fix rust-lang#34896.
…-errors Suggest constraining type parameter with `Clone` Fix rust-lang#34896.
…-errors Suggest constraining type parameter with `Clone` Fix rust-lang#34896.
…-errors Suggest constraining type parameter with `Clone` Fix rust-lang#34896.
https://is.gd/f2AX0B
This gives the very unintuitive error:
You expect
y.clone()
to return(*y).clone()
, i.e. aFoo
. It mysteriously returns an&Foo
instead.Because
&T
has a clone impl, it too, can be cloned (really, copied), returning a reference of the same lifetime. This is an operation you rarely want to do explicitly, except when dealing with generics.This error can crop up when you've forgotten to implement
Clone
onFoo
, and have a reference (which could have been silently inserted usingref
, as in the code above). However, it's not very obvious what's happening here. It can also crop up if you forget aT: Clone
boundWe should hint that
Foo
itself isn't cloneable and thus we fell back to cloning&Foo
here.This could be a lint on hitting the clone impl for references, but lints run too late.
I'm not sure how this can be implemented, since we need to see the source of a value and that's a bit tricky.
The text was updated successfully, but these errors were encountered: