|
1 | 1 | # Transitioning an existing project to a new edition
|
2 | 2 |
|
3 |
| -New editions might change the way you write Rust – they add new syntax, |
4 |
| -language, and library features, and also remove features. For example, `try`, |
5 |
| -`async`, and `await` are keywords in Rust 2018, but not Rust 2015. If you |
6 |
| -have a project that's using Rust 2015, and you'd like to use Rust 2018 for it |
7 |
| -instead, there's a few steps that you need to take. |
| 3 | +Rust includes tooling to automatically transition a project from one edition to the next. |
| 4 | +It will update your source code so that it is compatible with the next edition. |
| 5 | +Briefly, the steps to update to the next edition are: |
| 6 | + |
| 7 | +1. Run `cargo fix --edition` |
| 8 | +2. Edit `Cargo.toml` and set the `edition` field to the next edition, for example `edition = "2021"` |
| 9 | +3. Run `cargo build` or `cargo test` to verify the fixes worked. |
| 10 | + |
| 11 | +<!-- remove this when 2021 is stabilized --> |
| 12 | +> If you are migrating from 2018 to 2021, the steps are slightly different because 2021 is not yet stabilized, and is only available on the [nightly channel]. |
| 13 | +> The steps to follow are: |
| 14 | +> |
| 15 | +> 1. Install the most recent nightly: `rustup update nightly`. |
| 16 | +> 2. Run `cargo +nightly fix --edition`. |
| 17 | +> 3. Edit `Cargo.toml` and place `cargo-features = ["edition2021"]` at the top (above `[package]`), and change the edition field to say `edition = "2021"`. |
| 18 | +> 4. Run `cargo +nightly check` to verify it now works in the new edition. |
| 19 | +
|
| 20 | +The following sections dig into the details of these steps, and some of the issues you may encounter along the way. |
8 | 21 |
|
9 | 22 | > It's our intention that the migration to new editions is as smooth an
|
10 | 23 | > experience as possible. If it's difficult for you to upgrade to the latest edition,
|
11 | 24 | > we consider that a bug. If you run into problems with this process, please
|
12 |
| -> [file a bug](https://github.com/rust-lang/rust/issues/new). Thank you! |
| 25 | +> [file a bug](https://github.com/rust-lang/rust/issues/new/choose). Thank you! |
| 26 | +
|
| 27 | +## Starting the migration |
| 28 | + |
| 29 | +As an example, let's take a look at transitioning from the 2015 edition to the 2018 edition. |
| 30 | +The steps are essentially the same when transitioning to other editions like 2021. |
13 | 31 |
|
14 |
| -Here's an example. Imagine we have a crate that has this code in |
15 |
| -`src/lib.rs`: |
| 32 | +Imagine we have a crate that has this code in `src/lib.rs`: |
16 | 33 |
|
17 | 34 | ```rust
|
18 | 35 | trait Foo {
|
19 |
| - fn foo(&self, Box<Foo>); |
| 36 | + fn foo(&self, i32); |
20 | 37 | }
|
21 | 38 | ```
|
22 | 39 |
|
23 |
| -This code uses an anonymous parameter, that `Box<Foo>`. This is [not |
| 40 | +This code uses an anonymous parameter, that `i32`. This is [not |
24 | 41 | supported in Rust 2018](../rust-2018/trait-system/no-anon-params.md), and
|
25 | 42 | so this would fail to compile. Let's get this code up to date!
|
26 | 43 |
|
27 | 44 | ## Updating your code to be compatible with the new edition
|
28 | 45 |
|
29 |
| -Your code may or may not use features that are incompatible with the new |
30 |
| -edition. In order to help transition to Rust 2018, we've included a new |
31 |
| -subcommand with Cargo. To start, let's run it: |
| 46 | +Your code may or may not use features that are incompatible with the new edition. |
| 47 | +In order to help transition to the next edition, Cargo includes the [`cargo fix`] subcommand to automatically update your source code. |
| 48 | +To start, let's run it: |
32 | 49 |
|
33 | 50 | ```console
|
34 |
| -> cargo fix --edition |
| 51 | +cargo fix --edition |
35 | 52 | ```
|
36 | 53 |
|
37 | 54 | This will check your code, and automatically fix any issues that it can.
|
38 | 55 | Let's look at `src/lib.rs` again:
|
39 | 56 |
|
40 | 57 | ```rust
|
41 | 58 | trait Foo {
|
42 |
| - fn foo(&self, _: Box<Foo>); |
| 59 | + fn foo(&self, _: i32); |
43 | 60 | }
|
44 | 61 | ```
|
45 | 62 |
|
46 |
| -It's re-written our code to introduce a parameter name for that trait object. |
| 63 | +It's re-written our code to introduce a parameter name for that `i32` value. |
47 | 64 | In this case, since it had no name, `cargo fix` will replace it with `_`,
|
48 | 65 | which is conventional for unused variables.
|
49 | 66 |
|
50 | 67 | `cargo fix` can't always fix your code automatically.
|
51 | 68 | If `cargo fix` can't fix something, it will print the warning that it cannot fix
|
52 |
| -to the console. If you see one of these warnings, you'll have to update your code |
53 |
| -manually. See the corresponding section of this guide for help, and if you have |
54 |
| -problems, please seek help at the [user's forums](https://users.rust-lang.org/). |
55 |
| - |
56 |
| -Keep running `cargo fix --edition` until you have no more warnings. |
57 |
| - |
58 |
| -Congrats! Your code is now valid in both Rust 2015 and Rust 2018! |
| 69 | +to the console. If you see one of these warnings, you'll have to update your code manually. |
| 70 | +See the [Advanced migration strategies] chapter for more on working with the migration process, and read the chapters in this guide which explain which changes are needed. |
| 71 | +If you have problems, please seek help at the [user's forums](https://users.rust-lang.org/). |
59 | 72 |
|
60 | 73 | ## Enabling the new edition to use new features
|
61 | 74 |
|
62 | 75 | In order to use some new features, you must explicitly opt in to the new
|
63 |
| -edition. Once you're ready to commit, change your `Cargo.toml` to add the new |
| 76 | +edition. Once you're ready to continue, change your `Cargo.toml` to add the new |
64 | 77 | `edition` key/value pair. For example:
|
65 | 78 |
|
66 | 79 | ```toml
|
67 | 80 | [package]
|
68 | 81 | name = "foo"
|
69 | 82 | version = "0.1.0"
|
70 |
| -authors = ["Your Name <you@example.com>"] |
71 | 83 | edition = "2018"
|
72 | 84 | ```
|
73 | 85 |
|
74 | 86 | If there's no `edition` key, Cargo will default to Rust 2015. But in this case,
|
75 |
| -we've chosen `2018`, and so our code is compiling with Rust 2018! |
76 |
| - |
77 |
| -## Writing idiomatic code in a new edition |
78 |
| - |
79 |
| -Editions are not only about new features and removing old ones. In any programming |
80 |
| -language, idioms change over time, and Rust is no exception. While old code |
81 |
| -will continue to compile, it might be written with different idioms today. |
82 |
| - |
83 |
| -Our sample code contains an outdated idiom. Here it is again: |
84 |
| - |
85 |
| -```rust |
86 |
| -trait Foo { |
87 |
| - fn foo(&self, _: Box<Foo>); |
88 |
| -} |
89 |
| -``` |
90 |
| - |
91 |
| -In Rust 2018, it's considered idiomatic to use the [`dyn` |
92 |
| -keyword](../rust-2018/trait-system/dyn-trait-for-trait-objects.md) for |
93 |
| -trait objects. |
94 |
| - |
95 |
| -Eventually, we want `cargo fix` to fix all these idioms automatically in the same |
96 |
| -manner we did for upgrading to the 2018 edition. **Currently, |
97 |
| -though, the *"idiom lints"* are not ready for widespread automatic fixing.** The |
98 |
| -compiler isn't making `cargo fix`-compatible suggestions in many cases right |
99 |
| -now, and it is making incorrect suggestions in others. Enabling the idiom lints, |
100 |
| -even with `cargo fix`, is likely to leave your crate either broken or with many |
101 |
| -warnings still remaining. |
| 87 | +we've chosen `2018`, and so our code will compile with Rust 2018! |
102 | 88 |
|
103 |
| -We have plans to make these idiom migrations a seamless part of the Rust 2018 |
104 |
| -experience, but we're not there yet. As a result the following instructions are |
105 |
| -recommended only for the intrepid who are willing to work through a few |
106 |
| -compiler/Cargo bugs! |
| 89 | +The next step is to test your project on the new edition. |
| 90 | +Run your project tests to verify that everything still works, such as running [`cargo test`]. |
| 91 | +If new warnings are issued, you may want to consider running `cargo fix` again (without the `--edition` flag) to apply any suggestions given by the compiler. |
107 | 92 |
|
108 |
| -With that out of the way, we can instruct Cargo to fix our code snippet with: |
109 |
| - |
110 |
| -```console |
111 |
| -$ cargo fix --edition-idioms |
112 |
| -``` |
113 |
| - |
114 |
| -Afterwards, `src/lib.rs` looks like this: |
115 |
| - |
116 |
| -```rust |
117 |
| -trait Foo { |
118 |
| - fn foo(&self, _: Box<dyn Foo>); |
119 |
| -} |
120 |
| -``` |
121 |
| - |
122 |
| -We're now more idiomatic, and we didn't have to fix our code manually! |
123 |
| - |
124 |
| -Note that `cargo fix` may still not be able to automatically update our code. |
125 |
| -If `cargo fix` can't fix something, it will print a warning to the console, and |
126 |
| -you'll have to fix it manually. |
127 |
| - |
128 |
| -As mentioned before, there are known bugs around the idiom lints which |
129 |
| -means they're not all ready for prime time yet. You may get a scary-looking |
130 |
| -warning to report a bug to Cargo, which happens whenever a fix proposed by |
131 |
| -`rustc` actually caused code to stop compiling by accident. If you'd like `cargo |
132 |
| -fix` to make as much progress as possible, even if it causes code to stop |
133 |
| -compiling, you can execute: |
134 |
| - |
135 |
| -```console |
136 |
| -$ cargo fix --edition-idioms --broken-code |
137 |
| -``` |
138 |
| - |
139 |
| -This will instruct `cargo fix` to apply automatic suggestions regardless of |
140 |
| -whether they work or not. Like usual, you'll see the compilation result after |
141 |
| -all fixes are applied. If you notice anything wrong or unusual, please feel free |
142 |
| -to report an issue to Cargo and we'll help prioritize and fix it. |
| 93 | +Congrats! Your code is now valid in both Rust 2015 and Rust 2018! |
143 | 94 |
|
144 |
| -Enjoy the new edition! |
| 95 | +[`cargo fix`]: ../../cargo/commands/cargo-fix.html |
| 96 | +[`cargo test`]: ../../cargo/commands/cargo-test.html |
| 97 | +[Advanced migration strategies]: advanced-migrations.md |
| 98 | +[nightly channel]: ../../book/appendix-07-nightly-rust.html |
0 commit comments