Yes it took me 30 minutes. The error message in this case is uncharacteristically bad. Or I found it particularly confusing because of quirks in my understanding of rust’s type system.
Take a look. Do you think this quirk of derive is obvious from the error message alone? Would you have figured it out, in the context of a much more complex program with dozens of other changes that may or may not have been related?
The compiler error says my type didn’t implement clone. But #[derive(Clone)] was right there on my type, and my type was obviously cloneable. The error wasn’t on the derive - or anywhere nearby. My program even compiled successfully, right up until I tried to actually call clone() on my object. And my type trivially, obviously was cloneable because all the fields were clonable.
My first thought at the time was that my derive attribute was being ignored by the compiler somehow, but it wasn’t at all obvious why. The compiler’s suggested fix was also wrong and misleading. It suggests adding clone to an irrelevant type that shouldn’t impl clone in the first place. That’s the wrong fix.
In summary, the error message doesn’t offer the real problem, which is that the trait bounds added by derive Clone were wrong. And it didn’t suggest the proper fix - which was to impl clone manually.
I was very confused for a good while with this one. Get pissy if you want but I find this incredibly counterintuitive and I found the compiler’s error message to be uncharacteristically unhelpful.
If this quirk of derive was truly obvious, this blog post wouldn’t have hit the front page of HN in the first place. I cut my hand on one of rust’s sharp edges. Don’t get mad at me for bleeding a little.
The error message points you to the inner type and tells you to implement clone for it. Like you point out, it's sometimes not the correct fix - but the compiler can't be smart enough to tell you that. I'm actually at a loss for how this isn't anything but obvious if you know the language and type system. It's not magic!
My pet peeve is the learned helplessness around compiler error messages, particularly ones that go to great lengths to be informative and offer solutions instead of just throwing garbage at you.
> it's sometimes not the correct fix - but the compiler can't be smart enough to tell you that
Everyone said the same thing of most compiler errors until clang came along and showed everyone how much better compiler messages could be.
The compiler message here doesn’t suggest the true problem here, nor does it suggest the appropriate fix. I’m also clearly not the only one who finds this issue surprising and annoying. This blog post wouldn’t have been upvoted and commented on if it didn’t strike a nerve.
If nothing else, I think it’s quite obvious that the compiler’s error message could be improved. But better yet, I’d love to see it fixed in the language. The bounds derive places on its traits are simply wrong. There’s no reason why T needs to impl Clone. T is irrelevant.
For what it’s worth, I get what you’re frustrated about. I spent 2 years as a programming teacher. I feel like the first month of every cohort I wander around telling upset students that they forgot a semicolon. And the third month I wander around guiding frustrated students to read the compiler error message, which would have saved them 2 hours of guessing.
After banging my head into a wall for awhile on this issue, I made a reduced reproducing test case. Then I went looking in the rust compiler issue tracker. Only there did I finally see a proper explanation of what was going on, amidst a sea of other people struggling with the same thing.
That was half an hour of my life I won’t get back. I’m not helpless. But I am still pretty frustrated by the experience. I see it as a language level bug. It seems to take years and years of bike shedding for rust to fix stuff like this. I’d give even odds this still isn’t fixed in a decade from today.
But maybe, at least, we might be able to improve the error message?
Take a look. Do you think this quirk of derive is obvious from the error message alone? Would you have figured it out, in the context of a much more complex program with dozens of other changes that may or may not have been related?
https://play.rust-lang.org/?version=stable&mode=debug&editio...
The compiler error says my type didn’t implement clone. But #[derive(Clone)] was right there on my type, and my type was obviously cloneable. The error wasn’t on the derive - or anywhere nearby. My program even compiled successfully, right up until I tried to actually call clone() on my object. And my type trivially, obviously was cloneable because all the fields were clonable.
My first thought at the time was that my derive attribute was being ignored by the compiler somehow, but it wasn’t at all obvious why. The compiler’s suggested fix was also wrong and misleading. It suggests adding clone to an irrelevant type that shouldn’t impl clone in the first place. That’s the wrong fix.
In summary, the error message doesn’t offer the real problem, which is that the trait bounds added by derive Clone were wrong. And it didn’t suggest the proper fix - which was to impl clone manually.
I was very confused for a good while with this one. Get pissy if you want but I find this incredibly counterintuitive and I found the compiler’s error message to be uncharacteristically unhelpful.
If this quirk of derive was truly obvious, this blog post wouldn’t have hit the front page of HN in the first place. I cut my hand on one of rust’s sharp edges. Don’t get mad at me for bleeding a little.