-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Wrong suggestion on while_let_on_iterator #1033
Comments
This needs another trait impl lookup (where one first needs to construct the type of a ref of the expression, which would be |
It's also possible that it has to be That's what would have been required in my case, if the lint weren't rendered completely spurious by my decision to call |
@ssokolow I read through your post, and I'm very confused by the error. struct Foo<T> {
in_iter: T,
next_word: Vec<u32>,
}
impl<T: Iterator<Item=i32>> Foo<T> {
fn bar(&mut self) {
for x in &mut self.in_iter {
self.next_word.clear();
}
}
} works fine. Can you share some more code? |
Is this enough? impl<'a> WordOffsets<'a> {
/// Helper to deduplicate the code involved in advancing to the next word in the iterator
fn _next_word(&mut self, end_offset: usize, skip: bool) -> Option<(usize, usize)> {
// We have to update our state variables no matter what the outcome, so do this first.
let skipping = replace(&mut self.skipping, skip);
let start_offset = replace(&mut self.start_offset, end_offset);
// If our previous "word" is non-empty and we're not skipping it, return it
if start_offset < end_offset && !skipping {
Some((start_offset, end_offset))
} else {
None
}
}
}
impl<'a> Iterator for WordOffsets<'a> {
type Item = (usize, usize);
fn next(&mut self) -> Option<(usize, usize)> {
// Get the next grapheme cluster and its byte index
// Note: Using `while let` instead of `for` is necessary to avoid a borrow conflict
#[allow(while_let_on_iterator)]
while let Some((byte_offset, grapheme)) = self.in_iter.next() {
// Extract the base `char` so `classify_char` can call things like `is_uppercase`
let base = grapheme.chars().nth(0).expect("non-empty grapheme cluster");
// Identify character types and map transitions between them to actions
let curr_type = classify_char(base);
let curr_action = transition_to_action(replace(&mut self.prev_type, curr_type),
curr_type, self.strict);
// Actually apply the action to the iterator's state and, if the action returns an
// accumulated word, return it.
// TODO: Consider using an enum for the skip=true/false
let prev_offset = replace(&mut self.prev_offset, byte_offset);
if let Some(pair) = match curr_action {
CCaseAction::Skip => { self._next_word(byte_offset, true) },
CCaseAction::StartWord if self.suppress != byte_offset => {
self._next_word(byte_offset, false) },
CCaseAction::AlreadyStartedWord if self.suppress != prev_offset => {
self._next_word(prev_offset, false)
},
CCaseAction::Suppress => { self.suppress = byte_offset; None },
_ => { None }, // Use Literal as the fallback behaviour
} {
return Some(pair);
}
}
// Drain the remaining graphemes into a final word, if present
let in_len = self.in_len;
self._next_word(in_len, true)
}
} EDIT: ...and, huh. That code style looks noticeably less readable in GitHub's color scheme compared to Vim's default. |
Oh... I somehow misread that Yea, the only way to do that here would be to place So yea, we need to figure out whether a borrow is reused inside the loop before suggesting this change. |
Clippy will suggest to iterate over the supplied value without regards to borrowing. For example,
will lead clippy to produce the following suggestion:
wich would move
iter
out ofself
, which is clearly not what we want. The correct suggestion would be:But only if
&self.iter : Iterator<_>
. Otherwise the whole lint is wrong, and thewhile let
loop should be left alone.The text was updated successfully, but these errors were encountered: