Open
Description
I have a loop
with a match
which is suggested to convert to while let
. But it's important in this case that the borrows from the match
don't extend through the whole loop.
Here's my function:
/// Merges two sorted vectors into one.
pub fn merge_sorted<T>(xs: Vec<T>, ys: Vec<T>) -> Vec<T>
where T: PartialOrd {
let total_len = xs.len() + ys.len();
let mut res = Vec::with_capacity(total_len);
let mut ix = xs.into_iter().peekable();
let mut iy = ys.into_iter().peekable();
loop {
let lt = match (ix.peek(), iy.peek()) {
(Some(x), Some(y)) => x < y,
_ => break
};
res.push(if lt { &mut ix } else { &mut iy }.next().unwrap());
}
res.extend(ix);
res.extend(iy);
res
}
(Nevermind whether this is particularly good code -- I'm reconsidering that. But the lint is flawed regardless.)
Clippy's while_let_loop
suggests replacing the loop with:
while let (Some(x), Some(y)) = (ix.peek(), iy.peek()) {
res.push(if lt { &mut ix } else { &mut iy }.next().unwrap());
}
First of all, it missed the lt
binding. I can add let lt = x < y;
or use x < y
directly for that. But now the x
/y
borrows on ix
/iy
live for the entire loop body, so they can't be taken mutably for next()
.
error: cannot borrow `ix` as mutable more than once at a time [E0499]
res.push(if lt { &mut ix } else { &mut iy }.next().unwrap());
^~
[...]
error: cannot borrow `iy` as mutable more than once at a time [E0499]
res.push(if lt { &mut ix } else { &mut iy }.next().unwrap());
^~
Maybe non-lexical lifetimes could someday let this work, but for now it's a bad suggestion.
PS- while_let_loop
is missing from the wiki.