Take http://manishearth.github.io/blog/2015/05/17/the-problem-wit... for example...
Take http://manishearth.github.io/blog/2015/05/17/the-problem-wit... for example...
fn main() {
let mut x = 0;
let y = &x;
println!("{}", y);
x += 1;
println!("{}", x);
}
It still doesn't pass the borrow checker.What I do mean is, many times we have people drop by IRC and say "the borrow checker is dumb, I want to do X, and it won't let me" and the reply is something like "have you considered threading" and they go "ohhhhh I see." There was a good quote of the week about this at some point, but I can't find it right now.
I don't happen to run into patterns like the above code in real Rust code, personally. That doesn't mean that they don't happen, but I'm interested in _real world_ cases where this becomes an issue. We've got a bunch of them, which is why we're pursuing non-lexical lifetimes, but it seems like for many, this is a _constant_ struggle, and I run into a NLL situation maybe once every two months. Figuring out that disconnect is very interesting to me. It matters because I'm going to be responsible for teaching it, so real examples are way better than contrived ones. Moving that focus is the point of my current re-write of these docs :)
Your argument that for real world programs the borrow checkers conservatism does not create technical problems is completely plausible to me. The issue lies somewhere else.
There is a psychological component to this. People struggle with the borrow checker, or at least they feel like they did. This is negative for rust.
My point is that it would be better if it weren't trivial to write short, safe programs that are not accepted by the compiler.
Where can one expect the line to be drawn? I don't know. I worked with Isabelle/HOL to formalize mathematical proofs and there I saw that we can indeed expect a computer to be reasonably clever in abstract reasoning. I'm not saying that the rust compiler is dumb, however, there is room for improvement.
Thanks for your(plural) work on rust, btw.
(I even tried to get unsafe renamed to "trusted"... that didn't work out.)
Recently I was parsing a line-oriented, whitespace delimited file and had to introduce a temporary ("line", below):
let f = File::open(path)?;
let reader = BufReader::new(f);
for line_result in reader.lines() {
let line = line_result?;
let mut word_iter = line.split_whitespace();
because I think something didn't live long enough when I did line_result?.split_whitespace(). I forget exactly what the code was like before I got it past the borrow checker, though.For me, it seems like every time I dip a toe into rust I run into borrow/NLL issues right off the bat.
Ah, see, I'd go straight for Entry in the hash case. Which might be what you're referring to.
yeah, that later one isn't NLL: it's that
line_result?.split_whitespace()
^ ^
the ? will return your String, but then split_whitespace returns &strs to that String. Since it's not bound anywhere, the String would be deallocated at the end of the line, which would make the iterator dangling. NLL won't fix that.Thanks for the clarification about the second case not being solved by NLL. Those examples were the ones I had in my mental "code I would like the borrow checker to accept" bucket.
Would Niko's proposals in that internals thread you linked ("Accepting nested method calls with an `&mut self` receiver") eliminate the need for the temporary in that second example?