Help defeating the borrow checker (quick-xml)

I think my problem is best explained by code.

// `reader` is something that I can get events from. It borrows a buffer to do its work in.
let mut buf = vec![];
let mut event = Some(reader.read_event(&mut buf));

// parse an optional element
match event {
    Some(Event::Start(ref bytes)) if bytes.name() == "ElementName" => {
        // discard old event, freeing `buf`
        event = None;
        // discard used data
        buf.clear();
        // re-use `buf` to parse some other stuff.
        let el = parse_element(&mut reader, &mut buf);
    }
    _ => ()
}

// If we consumed the last event, then get another.
if event.is_none() {
    event = Some(reader.read_event(&mut buf));
}

// Now `event` contains either the first event if it was unused, or the next if it was

So here we try to parse an element that may or may not be present. I'm pretty sure that the above code is safe w.r.t. memory safety, but borrowck fails it because it doesn't see event = None as ending the borrow.

Does anyone know how I could change my code to avoid the borrow issue?

Gah, as always I immediately found a solution:

// `reader` is something that I can get events from. It borrows a buffer to do its work in.
let mut buf = vec![];
let mut event = reader.read_event(&mut buf);

// parse an optional element
match event {
    Event::Start(ref bytes) if bytes.name() == "ElementName" => {
        // discard old event, freeing `buf`
        drop(event);
        // discard used data
        buf.clear();
        // re-use `buf` to parse some other stuff.
        let el = parse_element(&mut reader, &mut buf);
        // replace contents of `event`.
        event = reader.read_event(&mut buf)?;
    }
    _ => ()
}

// Now `event` contains either the first event if it was unused, or the next if it was

The borrow checker is clever enough to allow event to be invalid for a region, as long as it is not used.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.