←back to thread

128 points RGBCube | 4 comments | | HN request time: 0s | source
Show context
loa_in_ ◴[] No.44497772[source]
Automatically deriving Clone is a convenience. You can and should write your own implementation for Clone whenever you need it and automatically derived implementation is insufficient.
replies(3): >>44498124 #>>44499705 #>>44500307 #
josephg ◴[] No.44498124[source]
But this issue makes it confusing & surprising when an automatically derived clone is sufficient and when its not. Its a silly extra rule that you have to memorise.

By the way, this issue also affects all of the other derivable traits in std - including PartialEq, Debug and others. Manually deriving all this stuff - especially Debug - is needless pain. Especially as your structs change and you need to (or forget to) maintain all this stuff.

Elegant software is measured in the number of lines of code you didn't need to write.

replies(4): >>44498182 #>>44498258 #>>44498373 #>>44498385 #
0rzech ◴[] No.44498182[source]
It's surprising up to the moment the compilation error tells you that all of the members have to implement derived trait.

Nevertheless, it would be cool to be able to add #[noderive(Trait)] or something to a field not to be included in automatic trait implementation. Especially that sometimes foreign types do not implement some traits and one has to implement lots of boilerplate just to ignore fields of those types.

I know of Derivative crate [1], but it's yet another dependency in an increasingly NPM-like dependency tree of a modern Rust project.

All in all, I resort to manual trait implementations when needed, just as GP.

[1] https://crates.io/crates/derivative

replies(2): >>44498752 #>>44499987 #
josephg ◴[] No.44499987[source]
> It's surprising up to the moment the compilation error tells you …

Unfortunately this problem only shows up when you’re combining derive with certain generic parameters for the first time. The first time I saw this, I thought the mistake was mine. It was so surprising and confusing that it took half an hour to figure out what the problem was. I thought it was a compiler bug for awhile and went to file it on the rust project - only to find lots of people had beat me to it.

Aside from anything else, it’d be great if rust had better error messages when you run into this issue.

replies(2): >>44501090 #>>44502883 #
estebank ◴[] No.44502883[source]
> Aside from anything else, it’d be great if rust had better error messages when you run into this issue.

Would you mind filing a ticket detailing what you'd wish the error had been? Without additional context, the only improvement I can think of is adding a note explaining imperfect derives when hitting a missing trait bound coming from a local crate derived impl.

replies(1): >>44505016 #
1. josephg ◴[] No.44505016[source]
I mentioned in a sibling comment. The error message doesn’t explain or suggest what the problem is, and it recommends the wrong fix. (It suggests implementing clone for T, whereas here you need to manually implement clone).

Something like this would have helped me immensely:

> Note: even though struct Foo has derive(Clone), Foo does not implement clone in this case. derive(Clone) may have overly restrictive trait bounds (impl Clone where T: Clone). If this is the case, you may need to manually implement Clone for Foo with less restrictive trait bounds:

    impl Clone for Foo {
        fn clone(&self) …
replies(1): >>44505822 #
2. estebank ◴[] No.44505822[source]
Would you mind filing a ticket on GitHub.com/rust-lang/rust with that exact request? (I'm on the go and am not logged on GitHub on this device and wouldn't want this feedback to be lost). This should be relatively easy to add and I agree it would be an improvement.
replies(1): >>44508171 #
3. josephg ◴[] No.44508171[source]
Sure - will do.
replies(1): >>44516367 #
4. josephg ◴[] No.44516367{3}[source]
https://github.com/rust-lang/rust/issues/143714