Avoid redundant clone suggestions in borrowck diagnostics#154197
Avoid redundant clone suggestions in borrowck diagnostics#154197yuk1ty wants to merge 1 commit intorust-lang:mainfrom
Conversation
|
r? @adwinwhite rustbot has assigned @adwinwhite. Use Why was this reviewer chosen?The reviewer was selected based on:
|
This comment has been minimized.
This comment has been minimized.
|
The failed tests tell me another case of the issue. Let me mark PR as draft. |
e986806 to
9020069
Compare
| /// Tracks which suggestions were emitted by [`MirBorrowckCtxt::explain_captures`], | ||
| /// so callers can avoid emitting redundant suggestions downstream. | ||
| struct ExplainCapturesResult { | ||
| clone_suggestion: CloneSuggestion, |
There was a problem hiding this comment.
it's fine to use bool here instead of enum
There was a problem hiding this comment.
9020069 to
1c123db
Compare
|
I'll possibly take a look today or tomorrow. I'm rather busy at the moment, so I wouldn't expect this to be that quick, to be honest. |
|
It seems that @Kivooeo is quite busy. I'll have a look. |
|
Some nits, otherwise it's a very nice improvement. Thank you for working on this! |
|
This PR also improves the diag for the case below, I think. use std::ops::Deref;
struct MyBox<T>(T);
impl<T> Deref for MyBox<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.0
}
}
pub fn main() {
let _x = MyBox(vec![1, 2]).into_iter();
// currently we have a simple clone help which is wrong. it's better to have UFCS.
} |
|
@rustbot author |
|
Reminder, once the PR becomes ready for a review, use |
|
Thank you! Let me try 👍 |
| self.explain_captures( | ||
| // The return value indicates whether a clone suggestion was emitted; | ||
| // redundancy is already handled via the `FnSelfUse` check below. | ||
| let _ = self.explain_captures( |
There was a problem hiding this comment.
This isn't a real result. I think the wildcard binding is unnecessary.
| moved_place: Place<'tcx>, | ||
| msg_opt: CapturedMessageOpt, | ||
| ) { | ||
| ) -> ExplainCapturesResult { |
There was a problem hiding this comment.
Would it be better to use a simple enum as return type? For readability and less indirect wrapper.
| span: Span, | ||
| use_spans: Option<UseSpans<'tcx>>, | ||
| ) -> Diag<'infcx> { | ||
| ) -> (Diag<'infcx>, bool) { |
There was a problem hiding this comment.
We don't really get what the bool means from the fn signature.
Fixes #153886
Removed redundant
.clone()suggestions.I found that there are two patterns to handle this issue while I was implementing:
.clone()For the target issue, we can just remove the UFCS (
<Option<String> as Clone>::clone(&selection.1)) side.However, for the
BorrowedContentSource::OverloadedDerefpattern likeRc<Vec<i32>>, for instance theborrowck-move-out-of-overloaded-auto-deref.rstest case, I think we need to employ the UFCS way. The actual test case is:And another error will be shown if we simply use the simple
.clone()pattern. Like:then we will get
Rust Playground
In this case,
Rc::cloneonly increments the reference count and returns a newRc<Vec<i32>>; it does not grant ownership of the innerVec<i32>. As a result, calling into_iter() attempts to move theVec<i32>, leading to the same E0507 error again.On the other hand, in UFCS form:
This explicitly calls
<Vec<i32> as Clone>::clone, and the argument&Rc<Vec<i32>>is treated as&Vec<i32>via Rc’sDerefimplementation. As a result, theVec<i32>itself is cloned, yielding an ownedVec<i32>, which allowsinto_iter()to succeed, if my understanding is correct.I addressed the issue as far as I could find the edge cases but please advice me if I'm overlooking something.