Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't use with Rust 2015 edition #248

Closed
RazrFalcon opened this issue May 27, 2019 · 2 comments
Closed

Can't use with Rust 2015 edition #248

RazrFalcon opened this issue May 27, 2019 · 2 comments

Comments

@RazrFalcon
Copy link

I have a code roughly like this:

fn parse_selectors<'i, 't>(
    input: &mut Parser<'i, 't>,
) -> Result<String, ParseError<'i, CustomParseError>> {
    let mut selectors = String::new();
    while let Ok(t) = input.next() {
        match t {
            Token::SquareBracketBlock => {
                selectors.push('[');

                input.parse_nested_block(|p| {
                    while let Ok(t) = p.next() {
                        /// ... 
                    }

                    Ok(())
                })?;

                selectors.push(']');
            }

            t => {
                unreachable!()
            }
        }
    }

    Ok(selectors)
}

It works fine with Rust 2018, but with 2015 I'm getting:

error[E0499]: cannot borrow `*input` as mutable more than once at a time
   --> src/lib.rs:134:17
    |
98  |     while let Ok(t) = input.next() {
    |                       -----      - first borrow ends here
    |                       |
    |                       first mutable borrow occurs here
...
134 |                 input.parse_nested_block(|p| {
    |                 ^^^^^ second mutable borrow occurs here

Is it not possible at all on Rust 2015 or I have to change a code somehow?

@SimonSapin
Copy link
Member

The difference is most likely non-lexical lifetimes, which rust-lang/rust#59114 (comment) enables in the 2015 edition as well. I think that will be in Rust 1.36.

Without NLL, you need to move the next use of input outside of the lexical scope where the return value of input.next() lives. Something like:

loop {
    let has_square_bracket = {
        match input.next() {
           Err(_) =>  break,
           Ok(Token::SquareBracketBlock) => true,
           Ok(_) => false,
        }
    };
    if has_square_bracket {
        input.parse_nested_block()
    }
}

Yes this is ugly. It’s why we have NLL :)

@RazrFalcon
Copy link
Author

Thanks. Looks like it's time to bump 1.18 to 1.32.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants