-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Iterator::cloned
: document side effect behavior
#92543
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
Conversation
(rust-highfive has picked a reviewer for you, use r? to override) |
436147f
to
703a639
Compare
/// on `iter.cloned().last()`, all elements will be cloned even if only the | ||
/// last one is actually returned. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it really worth making this guarantee? I could imagine a future compiler optimization (or perhaps specialization) that would eliminate clone
calls for non–side effecting Clone
implementors, such as Vec
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We will soon have a clippy lint for this, so no, I don't think we should sacrifice backwards compatibility for a possible perf gain.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe the clippy lint is the issue then?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, there is no backwards compatibility issue since the API contract currently does not promise this. It only becomes an issue once the guarantee is added.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is no "promise", but it has been observable behavior since 1.0.0. So if we were to change that, we better have a good idea if any code depends on it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also why would the clippy lint be an issue?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume the clippy lint is implying something about the side-effects since it was brought up here and since the lint is motivating this change? The lint itself wasn't linked, so I am just guessing.
There is no "promise", but it has been observable behavior since 1.0.0.
observable behavior != stability guarantee
This PR turns what someone might hypothetically rely on into a guarantee, that's a significant change that paints us into a corner.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not wedded to this PR – however I'd like to have the (non-)guarantees documented. I'd swap this out with "you should not rely on the items' Clone
impl being called for all items observed by the iterator" in a heartbeat if that's what we decide.
Leaving the observable behavior undocumented makes it harder to say "you shouldn't have relied on it" later.
#90209 intends to optimize away some clones here. |
Additionally this PR (saying that cloning always is a side-effect) is inconsistent with RFC 1521 |
The PR says "cloning is regarded as a side effect, becaue |
703a639
to
49632b9
Compare
It allows us to turn
The will clone part wouldn't be true in that case. |
Let's take a step back and see what the problem is and what options we have to deal with it: We see a performance footgun, in that elements may be needlessly cloned when e.g. doing So we can:
Is my analysis here correct? |
You have to consider code that clippy doesn't see, e.g. iterators returned by a function and then consumed by another function, possibly in another crate. Or generic code which takes And neither requires a documentation change. Just because a clippy lint is added we can still reserve the possibility of performing additional optimizations. And just because an optimization is added we do not necessarily need to document it. We have many optimizations in the standard library which are best-effort and not guaranteed. Some of them are observable if you look hard enough. There's also the second-order problem that if we add explicit non-guarantees to
At least the more general case |
That last point is a good one. I agree that the documentation should be centralized, but am not sure whether the So I'm closing this for now. Hope that #90209 is successful. 👍 |
During discussing work on clippy's upcoming
iter_overeager_cloned
lint, I found that the fact that thecloned
implementation never optimizes anyclone
call away because the clone implementation could contain an observable side effect is underdocumented in theIterator::cloned
method.This PR adds a note to rectify this omission.