, но это потребовало бы изменения внутренних типов методов способом, который мне не нравится :(

оложим, у меня есть несколько структур, как в следующем примере, и вnext() Метод, который мне нужно, чтобы получить следующее событие, используя предоставленный пользователем буфер, но если это событие является комментарием, а флаг игнорирования комментариев установлен в значение true, мне нужно снова извлечь следующее событие:

struct Parser {
    ignore_comments: bool,
}

enum XmlEvent<'buf> {
    Comment(&'buf str),
    Other(&'buf str),
}

impl Parser {
    fn next<'buf>(&mut self, buffer: &'buf mut String) -> XmlEvent<'buf> {
        let result = loop {
            buffer.clear();

            let temp_event = self.parse_outside_tag(buffer);

            match temp_event {
                XmlEvent::Comment(_) if self.ignore_comments => {}
                _ => break temp_event,
            }
        };
        result
    }

    fn parse_outside_tag<'buf>(&mut self, _buffer: &'buf mut String) -> XmlEvent<'buf> {
        unimplemented!()
    }
}

Этот код, однако, дает двойную ошибку заимствования, даже когда у меня есть#![feature(nll)] включено:

error[E0499]: cannot borrow `*buffer` as mutable more than once at a time
  --> src/main.rs:14:13
   |
14 |             buffer.clear();
   |             ^^^^^^ second mutable borrow occurs here
15 |             
16 |             let temp_event = self.parse_outside_tag(buffer);
   |                                                     ------ first mutable borrow occurs here
   |
note: borrowed value must be valid for the lifetime 'buf as defined on the method body at 12:5...
  --> src/main.rs:12:5
   |
12 |     fn next<'buf>(&mut self, buffer: &'buf mut String) -> XmlEvent<'buf> {
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error[E0499]: cannot borrow `*buffer` as mutable more than once at a time
  --> src/main.rs:16:53
   |
16 |             let temp_event = self.parse_outside_tag(buffer);
   |                                                     ^^^^^^ mutable borrow starts here in previous iteration of loop
   |
note: borrowed value must be valid for the lifetime 'buf as defined on the method body at 12:5...
  --> src/main.rs:12:5
   |
12 |     fn next<'buf>(&mut self, buffer: &'buf mut String) -> XmlEvent<'buf> {
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to 2 previous errors

Я могу (приблизительно, по крайней мере) понять, почему здесь может произойти ошибка с отключенной функцией NLL, но я не понимаю, почему это происходит с NLL.

В любом случае, моя конечная цель - реализовать это без флагов, поэтому я тоже попытался это сделать (это рекурсивно, что очень печально, но все нерекурсивные версии, которые я придумал, не могли работать без NLL):

fn next<'buf>(&mut self, buffer: &'buf mut String) -> XmlEvent<'buf> {
    buffer.clear();

    {
        let temp_event = self.parse_outside_tag(buffer);

        match temp_event {
            XmlEvent::Comment(_) if self.ignore_comments => {}
            _ => return temp_event,
        }
    }

    self.next(buffer)
}

Здесь я попытался ограничить заимствование внутри лексического блока, иничего из этого блока протекает наружу. Тем не менее, я все еще получаю сообщение об ошибке:

error[E0499]: cannot borrow `*buffer` as mutable more than once at a time
  --> src/main.rs:23:19
   |
15 |             let temp_event = self.parse_outside_tag(buffer);
   |                                                     ------ first mutable borrow occurs here
...
23 |         self.next(buffer)
   |                   ^^^^^^ second mutable borrow occurs here
24 |     }
   |     - first borrow ends here

error: aborting due to previous error

И опять NLL не исправляет это.

Прошло много времени с тех пор, как я столкнулся с ошибкой проверки заимствования, которую я не понимаю, поэтому я надеюсь, что это на самом деле нечто простое, что я почему-то упускаю из виду :)

Я действительно подозреваю, что коренная причина как-то связана с явным'buf время жизни (в частности, ошибки с включенным флагом NLL содержат эти примечания), но я не могу понять, что именно здесь не так.

Ответы на вопрос(1)

Ваш ответ на вопрос