Skip to content

Borrowing an immutable reference of a mutable reference through a function call in a loop is not accepted #51132

Open
@shepmaster

Description

@shepmaster

This code appears to be sound because event should either leave the loop or be thrown away before the next iteration:

#![feature(nll)]

fn next<'buf>(buffer: &'buf mut String) -> &'buf str {
    loop {
        let event = parse(buffer);

        if true {
            return event;
        }
    }
}

fn parse<'buf>(_buffer: &'buf mut String) -> &'buf str {
    unimplemented!()
}

fn main() {}

The current (1.28.0-nightly 2018-05-25 990d8aa) implementation still marks this as an error:

error[E0499]: cannot borrow `*buffer` as mutable more than once at a time
 --> src/main.rs:5:27
  |
5 |         let event = parse(buffer);
  |                           ^^^^^^ mutable borrow starts here in previous iteration of loop
  |
note: borrowed value must be valid for the lifetime 'buf as defined on the function body at 3:1...
 --> src/main.rs:3:1
  |
3 | fn next<'buf>(buffer: &'buf mut String) -> &'buf str {
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

@nikomatsakis said:

this should throw an error (for now) but this error should eventually go away. This is precisely a case where "Location sensitivity" is needed, but we removed that feature in the name of performance — once polonius support lands, though, this code would be accepted. That may or may not be before the edition.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-NLLArea: Non-lexical lifetimes (NLL)C-enhancementCategory: An issue proposing an enhancement or a PR with one.NLL-poloniusIssues related for using Polonius in the borrow checkerT-langRelevant to the language team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions