Mara Bos Profile picture
21 Oct, 17 tweets, 7 min read
A few hours ago, @rustlang 1.56 was released! πŸ¦€

This version ships with the new edition: Rust 2021! 🐊✨🎊

There's quite a few new features in the new version and edition:

Starting today, `cargo new` will use `edition = "2021"`. You can migrate your 2018 crates with `cargo fix --edition`.

These are all the edition changes:

1. `array.into_iter()` now iterates by value, instead of giving references.

(See for details.)

2/17 for (i, x) in [1, 2, 3].into_iter().enumerate() {        //
2. Closures in Rust 2021 will capture only the fields of an object you use, instead of the entire object. This should result in fewer fights with the borrow checker:

3/17 let mut x = ("a".to_string(), "b".to_str
3. In Rust 2021, `$x:pat` in macro_rules now accepts patterns that include a `|`, making your macro rules easier to write:

4/17 // Before, in Rust 2018: macro_rules! assert_match {     ($e
4. Specifying `edition = "2021"` in your Cargo.toml implies `resolver = "2"`, when not explicitly given.

See the announcement of Rust 1.51 for details on Cargo's new resolver:…

5/17 [package] name = "example" version = "1.0.0&q
5. In Rust 2021, you don't have to import the TryFrom, TryInto and FromIterator traits anymore. They are now part of the prelude, which is automatically imported into all your modules:

6/17 // No imports necessary!  fn f(x: u32) -> (i32, Vec<u8>) {
6. The panic!() (and assert) macros in Rust 2021 no longer behave inconsistently when given only one argument. This unblocks a feature that will be available in a few versions from now: implicit format arguments.

7/17 panic!("hey {}"); // Missing an argument like this
7. We reserved some syntax for identifiers and literals with prefixes in Rust 2021. This syntax doesn't mean anything *yet*, but reserving it means we can start giving meaning to it in the (near?) future:

8/17 // These are all syntax errors for now! These are just some
And finally the last change that's part of the 2021 edition:

8. Some old syntax that's been deprecated for a while is completely removed in Rust 2021. This means we can use that syntax for something else in the future. (Maybe we can use `...` for variadic generics.)

9/17 match x {     0...5  => a(), // This is now a hard error!
Then let's continue with the changes in Rust 1.56 that are available in all editions:

1. Extend<(A, B)> for (Extend<A>, Extend<B>)

It allows splitting an iterator over tuples into separate collections, a bit like the opposite of .zip():

10/17 let mut a = (Vec::new(), String::new());  let c = vec![(1, '
2. From<array> for BTreeMap, BTreeSet, HashMap, HashSet, VecDeque, LinkedList, and BinaryHeap.

You can now use e.g. BTreeMap::from(..) to make a collection with directly the contents you want:

11/17 let nums = BTreeMap::from([     (1, "one"),     (2
3. You can now combine `@` bindings with regular pattern bindings. That means you can now give a name to an object _and give a name to some parts of it_ at the same time:

12/17 let tuple @ (first, _) = (1, 2);  assert_eq!(first, 1); asse
4. BufWriter::into_parts()

BufWriter::into_inner() will try to flush the buffer before giving you back the underlying Write object, which can fail.

BufWriter::into_parts() cannot fail and gives you the Write object and the unflushed buffer, so you can handle it manually:

13/17 pub fn into_parts(self) -> (W, Result<Vec<u8>, WriterPanicke
5. A new .shrink_to() method on Vec, String, PathBuf, VecDeque, HashSet, etc.

This allows you to *reduce* the .capacity() of a collection. It is basically the opposite of .reserve():

14/17 pub fn shrink_to(&mut self, min_capacity: usize)  Shrinks th
6. const mem::transmute() 😬

You can now use std::mem::transmute to do horrible things in a const fn:

15/17 // This compiles now, but is still a bad idea!  const fn f(x
And finally, a new Cargo feature:

7. You can now specify the minimum supported Rust version in your Cargo.toml:

rust-version = "1.56.0"

If specified, Cargo will give users of your crate a clear error when their version of Rust is too old:

16/17 $ cat Cargo.toml [package] name = "example" versio
And that's the end of this thread!✨

For a more complete list of changes in Rust 1.56, check the release notes:


And for details on the 2021 edition, see:


β€’ β€’ β€’

Missing some Tweet in this thread? You can try to force a refresh

Keep Current with Mara Bos

Mara Bos Profile picture

Stay in touch and get notified when new unrolls are available from this author!

Read all threads

This Thread may be Removed Anytime!


Twitter may remove this content at anytime! Save it as PDF for later use!

Try unrolling a thread yourself!

how to unroll video
  1. Follow @ThreadReaderApp to mention us!

  2. From a Twitter thread mention us with a keyword "unroll"
@threadreaderapp unroll

Practice here first or read more on our help page!

More from @m_ou_se

9 Sep
πŸ¦€ Happy new Rust! πŸŽ†

Just now, @rustlang 1.55 was released, shipping with some small but very nice improvements.…

A thread:
πŸ¦€ 1. Half-open ranges in patterns.

Next to `start..=end`, you can now also use `start..` as a pattern to match on: fn f(x: u32) {     match x ...
πŸ¦€ 2. A better and faster floating point parsing algorithm in the standard library.

Functions like f64::from_str are now much faster, and a bunch of edge cases that failed to parse before are solved: // Much faster! let a: f64 ...
Read 11 tweets
6 May
The new stable version of @rustlang, Rust 1.52, was released just now! πŸ¦€πŸŽ‰

This release contains quite a few new small but significant features.

A thread.

My favourite new addition is `str::split_once`.

We already had str::split and str::splitn, which result in an iterator. But when parsing something simple, you often want to split something exactly once. For example, to parse a string containing `key=value`.

2/10   let s = "hello=world";   let (key, val) = s.spliScreenshot of the split_once and rsplit_once documentation.
Another one I'm excited about is one of the first features I worked on: std::fmt::Arguments::as_str()

fmt::Arguments is returned by format_args!(), and appears in macros that support formatting.

as_str() allows handling the literal case without special-casing your macro:

3/10 // Before  macro_rules! log {     ($msg:literal) => {       // After  macro_rules! log {     ($($args:tt)*) => {
Read 10 tweets
24 Apr
I just approved the PR for a very exciting addition to @rustlang 1.53: IntoIterator for arrays πŸŽ‰πŸ¦€

Before this change, only references to arrays implemented IntoIterator, which meant you could iterate over &[1,2,3] and &mut [1,2,3], but not over [1,2,3] directly.

1/6 error[E0277]: `[{integer}; 3]` is not an iterator  borrow thfor e in [1, 2, 3] { // Works in 1.53!     println!("{}
The reason we didn't add it sooner was backwards compatibility. `array.into_iter()` already compiles today, because of the way methods get resolved in Rust. This implicitly calls `(&array).into_iter()`. Adding the trait implementation would change the meaning and break code.

2/6 for e in [1, 2, 3].into_iter() {     // Surprise: `e` is a r
Technically we consider this type of breakage (adding a trait impl) 'minor' and acceptable. But there was too much code that would be broken by it. Thanks to @LukasKalbertodt, such code results in a warning nowadays, but there's a lot of code that just doesn't get updated.

3/6 warning: this method call currently resolves to `<&[T; N] as
Read 6 tweets
22 Apr
Lots of new standard library additions will become stable in @rustlang 1.53. πŸ¦€πŸŽ‰

1. Duration::ZERO, Duration::is_zero(), Duration::MAX pub const ZERO: Duration  A...
2. Duration::saturating_{add,sub,mul}

Since Durations cannot represent negative values, saturating_sub might come in handy to avoid panics. pub fn saturating_add(self, fn saturating_sub(self,...
Read 17 tweets

Did Thread Reader help you today?

Support us! We are indie developers!

This site is made by just two indie developers on a laptop doing marketing, support and development! Read more about the story.

Become a Premium Member ($3/month or $30/year) and get exclusive features!

Become Premium

Too expensive? Make a small donation by buying us coffee ($5) or help with server cost ($10)

Donate via Paypal Become our Patreon

Thank you for your support!

Follow Us on Twitter!