3

This program that I minified from my actual program doesn't compile, and I'm unable to understand why. In my mind, the non-lexical lifetime support should have obviated this case. Is this a compiler bug or am I missing something?

The point is that when a borrow happens with the call to get, it leads to a State that is borrowed from self. However, in case of State::One, the borrow should end and the next loop should be free of borrows. (According to my understanding of NLL, it should support these cases.) On the other hand, in case of State::Two a value originally borrowed from self is returned. The function signature states this is the case, and there shouldn't be any problem with that, as the loop terminates with the return self isn't used anymore.

A playground link: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=da8ca1dd9d5449eb1a6903d9a1e7ae41

struct Inner;

enum State<'a> {
    One,
    Two(&'a ()),
}

fn get<'s>(_inner: &'s mut Inner) -> State<'s> {
    unimplemented!()
}

struct Outer {
    inner: Inner,
}

impl Outer {
    pub fn read<'s>(&'s mut self) -> &'s () {
        loop {
            match get(&mut self.inner) {
                State::One => (), // In this case nothing happens, the borrow should end and the loop should continue
                State::Two(a) => return a, // self.inner ought to be borrowed for 's, that's just to be expected
            }
        }
    }
}
GolDDranks
  • 3,272
  • 4
  • 22
  • 30
  • 1
    "non-lexical" doesn't mean that the borrow checker can understand every possible invariant of your system in order to prove that a borrow is safe. It just means it is not _only_ constrained by lexical scope, as it was before. The term isn't particularly useful now that it is the default behaviour of the typechecker. – Peter Hall Nov 01 '19 at 17:56
  • Does this question help? https://stackoverflow.com/questions/50519147/double-mutable-borrow-error-in-a-loop-happens-even-with-nll-on – Peter Hall Nov 01 '19 at 17:59
  • 1
    The other question answers this question, but apparently marking it so makes me unable to send another answer (a workaround) to this question. I'm answering there to document the workaround. – GolDDranks Nov 02 '19 at 05:51

0 Answers0