You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
There are no automated migration tools for updating for the new resolver.
25
+
For most projects, there are usually few or no changes as a result of updating.
26
+
27
+
When updating with `cargo fix --edition`, Cargo will display a report if the new resolver will build dependencies with different features.
28
+
It may look something like this:
29
+
30
+
> note: Switching to Edition 2021 will enable the use of the version 2 feature resolver in Cargo.
31
+
> This may cause some dependencies to be built with fewer features enabled than previously.
32
+
> More information about the resolver changes may be found at <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/default-cargo-resolver.html><br>
33
+
> When building the following dependencies, the given features will no longer be used:
This lets you know that certain dependencies will no longer be built with the given features.
41
+
42
+
### Build failures
43
+
44
+
There may be some circumstances where your project may not build correctly after the change.
45
+
If a dependency declaration in one package assumes that certain features are enabled in another, and those features are now disabled, it may fail to compile.
46
+
47
+
For example, let's say we have a dependency like this:
48
+
49
+
```toml
50
+
# Cargo.toml
51
+
52
+
[dependencies]
53
+
bstr = { version = "0.2.16", default-features = false }
54
+
# ...
55
+
```
56
+
57
+
And somewhere in our dependency tree, another package has this:
58
+
59
+
```toml
60
+
# Another package's Cargo.toml
61
+
62
+
[build-dependencies]
63
+
bstr = "0.2.16"
64
+
```
65
+
66
+
In our package, we've been using the [`words_with_breaks`](https://docs.rs/bstr/0.2.16/bstr/trait.ByteSlice.html#method.words_with_breaks) method from `bstr`, which requires `bstr`'s "unicode" feature to be enabled.
67
+
This has historically worked because Cargo unified the features of `bstr` between the two packages.
68
+
However, after updating to Rust 2021, the new resolver will build `bstr` twice, once with the default features (as a build dependency), and once with no features (as our normal dependency).
69
+
Since `bstr` is now being built without the "unicode" feature, the `words_with_breaks` method doesn't exist, and the build will fail with an error that the method is missing.
70
+
71
+
The solution here is to ensure that the dependency is declared with the features you are actually using.
72
+
For example:
73
+
74
+
```toml
75
+
[dependencies]
76
+
bstr = { version = "0.2.16", default-features = false, features = ["unicode"] }
77
+
```
78
+
79
+
In some cases, this may be a problem with a third-party dependency that you don't have direct control over.
80
+
You can consider submitting a patch to that project to try to declare the correct set of features for the problematic dependency.
81
+
Alternatively, you can add features to any dependency from within your own `Cargo.toml` file.
82
+
For example, if the `bstr` example given above was declared in some third-party dependency, you can just copy the correct dependency declaration into your own project.
83
+
The features will be unified, as long as they match the unification rules of the new resolver. Those are:
84
+
85
+
* Features enabled on platform-specific dependencies for targets not currently being built are ignored.
86
+
* Build-dependencies and proc-macros do not share features with normal dependencies.
87
+
* Dev-dependencies do not activate features unless building a target that needs them (like tests or examples).
88
+
89
+
A real-world example is using [`diesel`](https://crates.io/crates/diesel) and [`diesel_migrations`](https://crates.io/crates/diesel_migrations).
90
+
These packages provide database support, and the database is selected using a feature, like this:
91
+
92
+
```toml
93
+
[dependencies]
94
+
diesel = { version = "1.4.7", features = ["postgres"] }
95
+
diesel_migrations = "1.4.0"
96
+
```
97
+
98
+
The problem is that `diesel_migrations` has an internal proc-macro which itself depends on `diesel`, and the proc-macro assumes its own copy of `diesel` has the same features enabled as the rest of the dependency graph.
99
+
After updating to the new resolver, it fails to build because now there are two copies of `diesel`, and the one built for the proc-macro is missing the "postgres" feature.
100
+
101
+
A solution here is to add `diesel` as a build-dependency with the required features, for example:
102
+
103
+
```toml
104
+
[build-dependencies]
105
+
diesel = { version = "1.4.7", features = ["postgres"] }
106
+
```
107
+
108
+
This causes Cargo to add "postgres" as a feature for host dependencies (proc-macros and build-dependencies).
109
+
Now, the `diesel_migrations` proc-macro will get the "postgres" feature enabled, and it will build correctly.
110
+
111
+
The 2.0 release of `diesel` (currently in development) does not have this problem as it has been restructured to not have this dependency requirement.
112
+
113
+
### Exploring features
114
+
115
+
The [`cargo tree`] command has had substantial improvements to help with the migration to the new resolver.
116
+
`cargo tree` can be used to explore the dependency graph, and to see which features are being enabled, and importantly *why* they are being enabled.
117
+
118
+
One option is to use the `--duplicates` flag (`-d` for short), which will tell you when a package is being built multiple times.
119
+
Taking the `bstr` example from earlier, we might see:
120
+
121
+
```console
122
+
> cargo tree -d
123
+
bstr v0.2.16
124
+
└── foo v0.1.0 (/MyProjects/foo)
125
+
126
+
bstr v0.2.16
127
+
[build-dependencies]
128
+
└── bar v0.1.0
129
+
└── foo v0.1.0 (/MyProjects/foo)
130
+
131
+
```
132
+
133
+
This output tells us that `bstr` is built twice, and shows the chain of dependencies that led to its inclusion in both cases.
134
+
135
+
You can print which features each package is using with the `-f` flag, like this:
136
+
137
+
```console
138
+
cargo tree -f '{p} {f}'
139
+
```
140
+
141
+
This tells Cargo to change the "format" of the output, where it will print both the package and the enabled features.
142
+
143
+
You can also use the `-e` flag to tell it which "edges" to display.
144
+
For example, `cargo tree -e features` will show in-between each dependency which features are being added by each dependency.
145
+
This option becomes more useful with the `-i` flag which can be used to "invert" the tree.
146
+
This allows you to see how features *flow* into a given dependency.
147
+
For example, let's say the dependency graph is large, and we're not quite sure who is depending on `bstr`, the following command will show that:
148
+
149
+
```console
150
+
> cargo tree -e features -i bstr
151
+
bstr v0.2.16
152
+
├── bstr feature "default"
153
+
│ [build-dependencies]
154
+
│ └── bar v0.1.0
155
+
│ └── bar feature "default"
156
+
│ └── foo v0.1.0 (/MyProjects/foo)
157
+
├── bstr feature "lazy_static"
158
+
│ └── bstr feature "unicode"
159
+
│ └── bstr feature "default" (*)
160
+
├── bstr feature "regex-automata"
161
+
│ └── bstr feature "unicode" (*)
162
+
├── bstr feature "std"
163
+
│ └── bstr feature "default" (*)
164
+
└── bstr feature "unicode" (*)
165
+
```
166
+
167
+
This snippet of output shows that the project `foo` depends on `bar` with the "default" feature.
168
+
Then, `bar` depends on `bstr` as a build-dependency with the "default" feature
169
+
We can further see that `bstr`'s "default" feature enables "unicode" (among other features).
0 commit comments