From 0fbf740ece45fe3bab5e6cff7a85d9e8696f3309 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 10 Jun 2022 18:31:52 -0400 Subject: [PATCH 1/9] add nll-by-default blog post NLL is finally going to be used by default! I'd like to highlight this achievement and in particular the hard work of a bunch of people. It also gives us a chance to hype up polonius and educate people a bit about some of the limitations of the existing borrow checker. --- posts/2022-06-10-nll-by-default.md | 53 ++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 posts/2022-06-10-nll-by-default.md diff --git a/posts/2022-06-10-nll-by-default.md b/posts/2022-06-10-nll-by-default.md new file mode 100644 index 000000000..e62a8091b --- /dev/null +++ b/posts/2022-06-10-nll-by-default.md @@ -0,0 +1,53 @@ +--- +layout: post +title: "Non-lexical lifetimes (NLL) fully stable" +author: Niko Matsakis +release: true +--- + +As of the Rust 1.63, the "non-lexical lifetimes" (NLL) work will be enabled by default. "But," I hear you saying, "wasn't NLL included in [Rust 2018]?" And yes, yes it was! But at that time, NLL was only enabled for Rust 2018 code, while Rust 2015 code ran in "migration mode". When in "migration mode," the compiler would run both the old *and* the new borrow checker and compare the results. This way, we could give warnings for older code that should never have compiled in the first place; we could also limit the impact of any bugs in the new code. Over time, we have limited migration mode to be closer and closer to just running the new-style borrow checker: in the next release, that process completes, and all Rust code will be checked with NLL. + +[Rust 2018]: https://blog.rust-lang.org/2018/12/06/Rust-1.31-and-rust-2018.html + +## How does removing the old borrow checker affect users? + +At this point, we have almost completely merged "migration mode" and "regular mode", so switching to NLL will have very little impact on the user experience. A number of diagnostics changed, mostly for the better -- [Jack Huey gives the full details in his blost post](https://jackh726.github.io/rust/2022/06/10/nll-stabilization.html). + +## Credit where credit is due + +The work to remove the old borrow checker has been going on for years. It's been a long, tedious, and largely thankless process. We'd like to take a moment to highlight the various people involved and make sure they are recognized for their hard work: + +* [Jack Huey](https://github.com/jackh726/), for driving the final details of stabilization (diagnostics, reconciling differences in behavior). +* [Élie Roudninski](https://github.com/marmeladema), for refactoring the diagnostics code and doing the painstaking work (along with Jack) of checking each regressed case, one by one. +* [Aaron Hill](https://github.com/Aaron1011), for numerous improvements to bring NLL diagnostics up to par. +* [Matthew Jasper](https://github.com/matthewjasper), for reconciling errors around higher-ranked lifetimes and other core diagnostics improvements. +* [Rémy Rakic](https://github.com/lqd), for rebasing Matthew's PR as well as doing other independent diagnostics work. +* [Christopher Vittal](https://github.com/chrisvittal), for removing "compare" mode (don't ask). +* [Centril](https://github.com/centril), for doing a lot of early work reconciling migration mode and the regular mode. +* And of course the members of the NLL working group (myself, [Felix Klock](https://github.com/pnkfelix), [Santiago Pastorino](https://github.com/spastorino), [Matthew Jasper](https://github.com/matthewjasper), [Paul Daniel Faria](https://github.com/nashenas88), [Nick Nethercote](https://github.com/nnethercote)) who delivered the feature in the first place. + +Jack's blog post includes a [detailed narrative](https://jackh726.github.io/rust/2022/06/10/nll-stabilization.html#how-did-we-get-here) of all the work involved if you'd like more details! It's a fun read. + +## Looking forward: what can we expect for the "borrow checker of the future"? + +The next frontier for Rust borrow checking is taking the [polonius](https://github.com/rust-lang/polonius) project and moving it from research experiment to production code. Polonius is a next-generation version of the borrow checker that was "spun off" from the main NLL effort in 2018, as we were getting NLL ready to ship in production. It's most important contribution is fixing a known limitation of the borrow checker, demonstrated by the following example: + +```rust= +fn last_or_push<'a>(vec: &'a mut Vec) -> &'a String { + if let Some(s) = vec.last() { // borrows vec + // returning s here forces vec to be borrowed + // for the rest of the function, even though it + // shouldn't have to be + return s; + } + + // Because vec is borrowed, this call to vec.push gives + // an error! + vec.push("".to_string()); // ERROR + vec.last().unwrap() +} +``` + +This example doesn't compile today ([try it for yourself](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=517ac32f0aab076faa32b9065783bbb4)), though there's not a good reason for that. You can often workaround the problem by editing the code to introduce a redundant if ([as shown in this example](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=d9b25963e83201902ecf5c02d79cbc13)), but with polonius, it will compile as is. If you'd like to learn more about how polonius (and the existing borrow checker) works[^name], you can [watch my talk from Rust Belt Rust](https://www.youtube.com/watch?v=_agDeiWek8w). + +[^name]: Or where the name "polonius" comes from! \ No newline at end of file From f0b6815475bc1cea2fc56d7c8f05e63f33b01c96 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 10 Jun 2022 19:43:01 -0400 Subject: [PATCH 2/9] add davidtwco and lqd my bad! --- posts/2022-06-10-nll-by-default.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/posts/2022-06-10-nll-by-default.md b/posts/2022-06-10-nll-by-default.md index e62a8091b..4901bdd6c 100644 --- a/posts/2022-06-10-nll-by-default.md +++ b/posts/2022-06-10-nll-by-default.md @@ -24,7 +24,7 @@ The work to remove the old borrow checker has been going on for years. It's been * [Rémy Rakic](https://github.com/lqd), for rebasing Matthew's PR as well as doing other independent diagnostics work. * [Christopher Vittal](https://github.com/chrisvittal), for removing "compare" mode (don't ask). * [Centril](https://github.com/centril), for doing a lot of early work reconciling migration mode and the regular mode. -* And of course the members of the NLL working group (myself, [Felix Klock](https://github.com/pnkfelix), [Santiago Pastorino](https://github.com/spastorino), [Matthew Jasper](https://github.com/matthewjasper), [Paul Daniel Faria](https://github.com/nashenas88), [Nick Nethercote](https://github.com/nnethercote)) who delivered the feature in the first place. +* And of course the members of the NLL working group (myself, [Felix Klock](https://github.com/pnkfelix), [Santiago Pastorino](https://github.com/spastorino), [Matthew Jasper](https://github.com/matthewjasper), [David Wood](https://github.com/davidtwco], [Rémy Rakic](https://github.com/lqd), [Paul Daniel Faria](https://github.com/nashenas88), [Nick Nethercote](https://github.com/nnethercote)) who delivered the feature in the first place. Jack's blog post includes a [detailed narrative](https://jackh726.github.io/rust/2022/06/10/nll-stabilization.html#how-did-we-get-here) of all the work involved if you'd like more details! It's a fun read. @@ -50,4 +50,4 @@ fn last_or_push<'a>(vec: &'a mut Vec) -> &'a String { This example doesn't compile today ([try it for yourself](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=517ac32f0aab076faa32b9065783bbb4)), though there's not a good reason for that. You can often workaround the problem by editing the code to introduce a redundant if ([as shown in this example](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=d9b25963e83201902ecf5c02d79cbc13)), but with polonius, it will compile as is. If you'd like to learn more about how polonius (and the existing borrow checker) works[^name], you can [watch my talk from Rust Belt Rust](https://www.youtube.com/watch?v=_agDeiWek8w). -[^name]: Or where the name "polonius" comes from! \ No newline at end of file +[^name]: Or where the name "polonius" comes from! From 10e3e519295e292474e5dbfa26d9e62d47371afa Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 10 Jun 2022 19:43:51 -0400 Subject: [PATCH 3/9] "it's" is not possessive, dang it --- posts/2022-06-10-nll-by-default.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/posts/2022-06-10-nll-by-default.md b/posts/2022-06-10-nll-by-default.md index 4901bdd6c..836917474 100644 --- a/posts/2022-06-10-nll-by-default.md +++ b/posts/2022-06-10-nll-by-default.md @@ -30,7 +30,7 @@ Jack's blog post includes a [detailed narrative](https://jackh726.github.io/rust ## Looking forward: what can we expect for the "borrow checker of the future"? -The next frontier for Rust borrow checking is taking the [polonius](https://github.com/rust-lang/polonius) project and moving it from research experiment to production code. Polonius is a next-generation version of the borrow checker that was "spun off" from the main NLL effort in 2018, as we were getting NLL ready to ship in production. It's most important contribution is fixing a known limitation of the borrow checker, demonstrated by the following example: +The next frontier for Rust borrow checking is taking the [polonius](https://github.com/rust-lang/polonius) project and moving it from research experiment to production code. Polonius is a next-generation version of the borrow checker that was "spun off" from the main NLL effort in 2018, as we were getting NLL ready to ship in production. Its most important contribution is fixing a known limitation of the borrow checker, demonstrated by the following example: ```rust= fn last_or_push<'a>(vec: &'a mut Vec) -> &'a String { From d159f2651df56fe29c2b8ab45b42d425f0653e38 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 10 Jun 2022 19:44:17 -0400 Subject: [PATCH 4/9] silly hackmd, that = sign is annoying --- posts/2022-06-10-nll-by-default.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/posts/2022-06-10-nll-by-default.md b/posts/2022-06-10-nll-by-default.md index 836917474..0d534ec82 100644 --- a/posts/2022-06-10-nll-by-default.md +++ b/posts/2022-06-10-nll-by-default.md @@ -32,7 +32,7 @@ Jack's blog post includes a [detailed narrative](https://jackh726.github.io/rust The next frontier for Rust borrow checking is taking the [polonius](https://github.com/rust-lang/polonius) project and moving it from research experiment to production code. Polonius is a next-generation version of the borrow checker that was "spun off" from the main NLL effort in 2018, as we were getting NLL ready to ship in production. Its most important contribution is fixing a known limitation of the borrow checker, demonstrated by the following example: -```rust= +```rust fn last_or_push<'a>(vec: &'a mut Vec) -> &'a String { if let Some(s) = vec.last() { // borrows vec // returning s here forces vec to be borrowed From d299737d9c3d006b605981b806b91d39fd47a55f Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 10 Jun 2022 19:47:49 -0400 Subject: [PATCH 5/9] add a team designation --- posts/2022-06-10-nll-by-default.md | 1 + 1 file changed, 1 insertion(+) diff --git a/posts/2022-06-10-nll-by-default.md b/posts/2022-06-10-nll-by-default.md index 0d534ec82..f242c7318 100644 --- a/posts/2022-06-10-nll-by-default.md +++ b/posts/2022-06-10-nll-by-default.md @@ -2,6 +2,7 @@ layout: post title: "Non-lexical lifetimes (NLL) fully stable" author: Niko Matsakis +team: the NLL working group release: true --- From 98dc8a7b70a6dfaec56d9078109b80b2cd5836b4 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 10 Jun 2022 21:39:00 -0400 Subject: [PATCH 6/9] Apply suggestions from code review Co-authored-by: Josh Triplett --- posts/2022-06-10-nll-by-default.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/posts/2022-06-10-nll-by-default.md b/posts/2022-06-10-nll-by-default.md index f242c7318..3f99b6526 100644 --- a/posts/2022-06-10-nll-by-default.md +++ b/posts/2022-06-10-nll-by-default.md @@ -18,14 +18,14 @@ At this point, we have almost completely merged "migration mode" and "regular mo The work to remove the old borrow checker has been going on for years. It's been a long, tedious, and largely thankless process. We'd like to take a moment to highlight the various people involved and make sure they are recognized for their hard work: -* [Jack Huey](https://github.com/jackh726/), for driving the final details of stabilization (diagnostics, reconciling differences in behavior). +* [Jack Huey](https://github.com/jackh726/) ([sponsorship page](https://github.com/sponsors/jackh726)), for driving the final details of stabilization (diagnostics, reconciling differences in behavior). * [Élie Roudninski](https://github.com/marmeladema), for refactoring the diagnostics code and doing the painstaking work (along with Jack) of checking each regressed case, one by one. * [Aaron Hill](https://github.com/Aaron1011), for numerous improvements to bring NLL diagnostics up to par. * [Matthew Jasper](https://github.com/matthewjasper), for reconciling errors around higher-ranked lifetimes and other core diagnostics improvements. * [Rémy Rakic](https://github.com/lqd), for rebasing Matthew's PR as well as doing other independent diagnostics work. * [Christopher Vittal](https://github.com/chrisvittal), for removing "compare" mode (don't ask). * [Centril](https://github.com/centril), for doing a lot of early work reconciling migration mode and the regular mode. -* And of course the members of the NLL working group (myself, [Felix Klock](https://github.com/pnkfelix), [Santiago Pastorino](https://github.com/spastorino), [Matthew Jasper](https://github.com/matthewjasper), [David Wood](https://github.com/davidtwco], [Rémy Rakic](https://github.com/lqd), [Paul Daniel Faria](https://github.com/nashenas88), [Nick Nethercote](https://github.com/nnethercote)) who delivered the feature in the first place. +* And of course the members of the NLL working group (myself, [Felix Klock](https://github.com/pnkfelix), [Santiago Pastorino](https://github.com/spastorino) ([sponsorship page](https://github.com/sponsors/spastorino)), [Matthew Jasper](https://github.com/matthewjasper), [David Wood](https://github.com/davidtwco), [Rémy Rakic](https://github.com/lqd), [Paul Daniel Faria](https://github.com/nashenas88), [Nick Nethercote](https://github.com/nnethercote)) who delivered the feature in the first place. Jack's blog post includes a [detailed narrative](https://jackh726.github.io/rust/2022/06/10/nll-stabilization.html#how-did-we-get-here) of all the work involved if you'd like more details! It's a fun read. From 6975b224afd35125313c687e5346b483b1487077 Mon Sep 17 00:00:00 2001 From: Jack Huey <31162821+jackh726@users.noreply.github.com> Date: Wed, 3 Aug 2022 20:07:39 -0400 Subject: [PATCH 7/9] Review and clarification on NLL --- posts/2022-06-10-nll-by-default.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/posts/2022-06-10-nll-by-default.md b/posts/2022-06-10-nll-by-default.md index 3f99b6526..9e7a583bc 100644 --- a/posts/2022-06-10-nll-by-default.md +++ b/posts/2022-06-10-nll-by-default.md @@ -3,16 +3,17 @@ layout: post title: "Non-lexical lifetimes (NLL) fully stable" author: Niko Matsakis team: the NLL working group -release: true +release: false --- -As of the Rust 1.63, the "non-lexical lifetimes" (NLL) work will be enabled by default. "But," I hear you saying, "wasn't NLL included in [Rust 2018]?" And yes, yes it was! But at that time, NLL was only enabled for Rust 2018 code, while Rust 2015 code ran in "migration mode". When in "migration mode," the compiler would run both the old *and* the new borrow checker and compare the results. This way, we could give warnings for older code that should never have compiled in the first place; we could also limit the impact of any bugs in the new code. Over time, we have limited migration mode to be closer and closer to just running the new-style borrow checker: in the next release, that process completes, and all Rust code will be checked with NLL. +As of the Rust 1.63, the "non-lexical lifetimes" (NLL) work will be enabled by default. NLL is the second iteration of Rust's borrow checker. The [RFC] actually does quite a nice job of highlighting some of the motivating examples. "But," I hear you saying, "wasn't NLL included in [Rust 2018]?" And yes, yes it was! But at that time, NLL was only enabled for Rust 2018 code, while Rust 2015 code ran in "migration mode". When in "migration mode," the compiler would run both the old *and* the new borrow checker and compare the results. This way, we could give warnings for older code that should never have compiled in the first place; we could also limit the impact of any bugs in the new code. Over time, we have limited migration mode to be closer and closer to just running the new-style borrow checker: in the next release, that process completes, and all Rust code will be checked with NLL. +[RFC]: https://rust-lang.github.io/rfcs/2094-nll.html [Rust 2018]: https://blog.rust-lang.org/2018/12/06/Rust-1.31-and-rust-2018.html ## How does removing the old borrow checker affect users? -At this point, we have almost completely merged "migration mode" and "regular mode", so switching to NLL will have very little impact on the user experience. A number of diagnostics changed, mostly for the better -- [Jack Huey gives the full details in his blost post](https://jackh726.github.io/rust/2022/06/10/nll-stabilization.html). +At this point, we have almost completely merged "migration mode" and "regular mode", so switching to NLL will have very little impact on the user experience. A number of diagnostics changed, mostly for the better -- [Jack Huey gives the full details in his blog post](https://jackh726.github.io/rust/2022/06/10/nll-stabilization.html). ## Credit where credit is due From 051875016e135ea82ff92d8b1d32472c733144a3 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Thu, 4 Aug 2022 16:52:29 -0400 Subject: [PATCH 8/9] Move post date --- ...{2022-06-10-nll-by-default.md => 2022-08-05-nll-by-default.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename posts/{2022-06-10-nll-by-default.md => 2022-08-05-nll-by-default.md} (100%) diff --git a/posts/2022-06-10-nll-by-default.md b/posts/2022-08-05-nll-by-default.md similarity index 100% rename from posts/2022-06-10-nll-by-default.md rename to posts/2022-08-05-nll-by-default.md From b98cc1ba44219b9995219c3a5daecbc5f5f8918c Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Thu, 4 Aug 2022 16:53:04 -0400 Subject: [PATCH 9/9] Update posts/2022-08-05-nll-by-default.md --- posts/2022-08-05-nll-by-default.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/posts/2022-08-05-nll-by-default.md b/posts/2022-08-05-nll-by-default.md index 9e7a583bc..b32d1058e 100644 --- a/posts/2022-08-05-nll-by-default.md +++ b/posts/2022-08-05-nll-by-default.md @@ -6,7 +6,7 @@ team: the NLL working group