Skip to content

Commit 260ff85

Browse files
authored
Merge pull request #440 from nikomatsakis/nll-transition-to-hard-error
NLL transition
2 parents 6d6918f + c54315b commit 260ff85

File tree

1 file changed

+109
-0
lines changed

1 file changed

+109
-0
lines changed

posts/2019-11-01-nll-hard-errors.md

+109
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
---
2+
layout: post
3+
title: "Completing the transition to the new borrow checker"
4+
author: Niko Matsakis
5+
---
6+
7+
For most of 2018, we've been issuing warnings about various bugs in the
8+
borrow checker that we plan to fix -- about two months ago, in the
9+
current Rust nightly, those warnings became **hard errors**. In about
10+
two weeks, when the nightly branches to become beta, those hard errors
11+
will be in the beta build, and they will eventually hit stable on
12+
December 19th, as part of Rust 1.40.0. **If you're testing with
13+
Nightly, you should be all set -- but otherwise, you may want to go
14+
and check to make sure your code still builds. If not, we have advice
15+
for fixing common problems below.**
16+
17+
### Background: the non-lexical lifetime transition
18+
19+
When we [released Rust 2018 in Rust 1.31][2018], it included a new
20+
version of the borrow checker, one that implemented ["non-lexical
21+
lifetimes"][nll]. This new borrow checker did a much more precise
22+
analysis than the original, allowing us to eliminate a lot of
23+
unnecessary errors and make Rust easier to use. I think most everyone
24+
who was using Rust 2015 can attest that this shift was a big
25+
improvement.
26+
27+
### The new borrow checker also fixed a lot of bugs
28+
29+
What is perhaps less well understood is that the new borrow checker
30+
implementation *also* fixed a lot of bugs. In other words, the new
31+
borrow checker did not just accept more programs -- **it also rejected
32+
some programs that were only accepted in the first place due to memory
33+
unsafety bugs in the old borrow checker!**
34+
35+
[2018]: https://blog.rust-lang.org/2018/12/06/Rust-1.31-and-rust-2018.html
36+
[nll]: https://blog.rust-lang.org/2018/12/06/Rust-1.31-and-rust-2018.html#non-lexical-lifetimes
37+
[MIR]: https://blog.rust-lang.org/2016/04/19/MIR.html
38+
39+
### Until recently, those fixed bugs produced warnings, not errors
40+
41+
Obviously, we don't want to accept programs that could undermine
42+
Rust's safety guarantees. At the same time, as part of our commitment
43+
to stability, we try to avoid making sudden bug fixes that will affect
44+
a lot of code. Whenever possible, we prefer to "phase in" those
45+
changes gradually. We usually begin with "Future Compatibility
46+
Warnings", for example, before moving those warnings to hard errors
47+
(sometimes a small bit at a time). Since the bug fixes to the borrow
48+
checker affected a lot of crates, we knew we needed a warning period
49+
before we could make them into hard errors.
50+
51+
To implement this warning period, we kept two copies of the borrow
52+
checker around (this is a trick we use quite frequently, actually).
53+
The new checker ran first. If it found errors, we didn't report them
54+
directly: instead, we ran the old checker in order to see if the crate
55+
*used* to compile before. If so, we reported the errors as Future
56+
Compatibility Warnings, since we were changing something that used to
57+
compile into errors.
58+
59+
### All good things must come to an end; and bad ones, too
60+
61+
Over time we have been slowly transitioning those future compatibility
62+
warnings into errors, a bit at a time. About two months ago, we
63+
decided that the time had come to finish the job. So, over the course
64+
of two PRs, we [converted all remaining warnings to errors][a] and
65+
then [removed the old borrow checker implementation][b].
66+
67+
[a]: https://github.com/rust-lang/rust/pull/63565
68+
[b]: https://github.com/rust-lang/rust/pull/64790
69+
70+
### What this means for you
71+
72+
**If you are testing your package with nightly, then you should be
73+
fine.** In fact, even if you build on stable, we always recommend that
74+
you test your builds in CI with the nightly build, so that you can
75+
identify upcoming issues early and report them to us.
76+
77+
**Otherwise, you may want to check your dependencies.** When we
78+
decided to remove the old borrow checker, we also analyzed which
79+
crates would stop compiling. For anything that seemed to be widely
80+
used, we made sure that there were newer versions of that crate
81+
available that *do* compile (for the most part, this had all already
82+
happened during the warning period). But if you have those older
83+
versions in your `Cargo.lock` file, and you are only using stable
84+
builds, then you may find that your code no longer builds once 1.40.0
85+
is released -- you will have to upgrade the dependency.
86+
87+
The most common crates that were affected are the following:
88+
89+
* `url` version 1.7.0 -- you can upgrade to 1.7.2, though you'd be better off upgrading to 2.1.0
90+
* `nalgebra` version 0.16.13 -- you can upgrade to 0.16.14, though you'd be better off upgrading to 0.19.0
91+
* `rusttype` version 0.2.0 to 0.2.3 -- you can upgrade to 0.2.4, though you'd be better upgrading to 0.8.1
92+
93+
You can find out which crates you rely upon using the [cargo-tree] command. If you find
94+
that you *do* rely (say) on `url` 1.7.0, you can upgrade to 1.7.2 by executing:
95+
96+
```bash
97+
cargo update --package url --precise 1.7.2
98+
```
99+
100+
[cargo-tree]: https://crates.io/crates/cargo-tree
101+
102+
### Want to learn more?
103+
104+
If you'd like to learn more about the kinds of bugs that were fixed --
105+
or if you are seeing errors in your code that you need to fix -- take
106+
a look at this [excellent blog post by Felix Klock][nllpost], which
107+
goes into great detail.
108+
109+
[nllpost]: http://blog.pnkfx.org/blog/2019/06/26/breaking-news-non-lexical-lifetimes-arrives-for-everyone/

0 commit comments

Comments
 (0)