Reputation: 8092
This code:
fn t(r: &[u8]) {
match r {
_ if r.iter().any(|&x| x == b';') => {}
_ => {}
}
}
gives me the error:
error[E0301]: cannot mutably borrow in a pattern guard
|
10 | _ if r.iter().any(|&x| x == b';') => {}
| ^^^^^^^^ borrowed mutably in pattern guard
I understand that I can not borrow mutably in match patterns, but why does the compiler think that r.iter()
borrows mutably? There is a separate method iter_mut
for borrowing mutably.
And how can I check that &[u8]
contains b';'
without introducing separate functions?
Upvotes: 5
Views: 327
Reputation: 430851
The error message is a bit more nuanced — iter
doesn't borrow mutably, but the result of iter
is being borrowed mutably. This is because Iterator::any
takes self
by mutable reference:
fn any<F>(&mut self, f: F) -> bool
where
F: FnMut(Self::Item) -> bool,
Here's a reproduction:
struct X;
impl X {
fn new() -> X { X }
fn predicate(&mut self) -> bool { true }
}
fn main() {
match () {
_ if X::new().predicate() => {}
_ => {}
}
}
I'd just check if the slice contains
the value:
fn t(r: &[u8]) {
match r {
_ if r.contains(&b';') => {}
_ => {}
}
}
Realistically, this is an example of the borrow checker being overly aggressive. Mutably borrowing something from "outside" the match guard is a bad idea, but mutably borrowing something created in the match guard should be safe.
It's likely that this particular case would work when the borrow checker is rewritten to use Rust's MIR layer.
See also:
Upvotes: 6