Why does iter borrow mutably when used in a security template?

This code:

fn t(r: &[u8]) {
    match r {
        _ if r.iter().any(|&x| x == b';') => {}
        _ => {}
    }
}

gives me an 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’t borrow mutably in match patterns, but why does the compiler think it's being r.iter()seen with a change? There is a separate method iter_mutfor borrowing with change.

And how can I check what it &[u8]contains b';'without introducing individual functions?

+4
source share
1 answer

The error message is a little more subtle - it iterdoes not borrow variably, but the result is iterborrowed with the change. This is because it Iterator::anytakes on a value selfvia a mutable link:

fn any<F>(&mut self, f: F) -> bool 
where
    F: FnMut(Self::Item) -> bool, 

Here's the reproduction:

struct X;

impl X {
    fn new() -> X { X } 
    fn predicate(&mut self) -> bool { true }
}

fn main() {
    match () {
        _ if X::new().predicate() => {}
        _ => {}
    }
}

, contains :

fn t(r: &[u8]) {
    match r {
        _ if r.contains(&b';') => {}
        _ => {}
    }
}

, , . - "", - , -, , .

, , MIR Rust.

. :

+5

Source: https://habr.com/ru/post/1681015/


All Articles