Skip to content

Commit df73835

Browse files
Adjust for release
1 parent 921dd0c commit df73835

File tree

1 file changed

+12
-21
lines changed

1 file changed

+12
-21
lines changed

posts/2021-03-25-Rust-1.51.0.md

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -66,27 +66,13 @@ struct Array<u8, 32> {
6666
}
6767
```
6868

69-
Const generics also allows to write our methods in a new way. Let's see what a `fn last(&self) -> Option<&T>` implementation could look like:
70-
71-
```rust
72-
impl<T, const LENGTH: usize> Array<T, LENGTH> {
73-
fn last(&self) -> Option<&T> {
74-
if LENGTH == 0 {
75-
// ^^^^^^^^^^^ This is always `true` for `Array<T, 0>`.
76-
None
77-
} else {
78-
Some(&self.list[LENGTH - 1])
79-
}
80-
}
81-
}
82-
```
83-
8469
Const generics adds an important new tool for library designers in creating new, powerful compile-time safe APIs. If you'd like to learn more about const generics you can also check out the ["Const Generics MVP Hits Beta"][const-generics-blog] blog post for more information about the feature and its current restrictions. We can't wait to see what new libraries and APIs you create!
8570

8671
[const-generics-blog]: https://blog.rust-lang.org/2021/02/26/const-generics-mvp-beta.html
8772

8873
### `array::IntoIter` Stabilisation
89-
As part of const generics stabilising, we're also stabilising a new API that uses it called `array::IntoIter`. `IntoIter` allows you to create a by value iterator over any array. Previously you had to use `[T]`'s (a slice) iterator implementation which returned `&T`, which you then needed to read and copy. Now you can directly iterate over the values without additional copies. *Note:* that `IntoIter::new` may be deprecated once it is possible for arrays to implement `IntoIterator` directly.
74+
75+
As part of const generics stabilising, we're also stabilising a new API that uses it, `std::array::IntoIter`. `IntoIter` allows you to create a by value iterator over any array. Previously there wasn't a convenient way to iterate over owned values of an array, only references to them.X
9076

9177
```rust
9278
fn main() {
@@ -104,8 +90,13 @@ fn main() {
10490
}
10591
```
10692

93+
Note that this is added as a separate method instead of `.into_iter()` on arrays, as that currently introduces some amount of breakage; currently `.into_iter()` refers to the slice by-reference iterator. We're exploring ways to make this more ergonomic in the future.
94+
10795
### Cargo's New Feature Resolver
108-
Dependency management is a hard problem, and one of the hardest parts of it is just picking what *version* of a dependency to use when it's depended on by two different packages. This doesn't just include its version number, but also what features are or aren't enabled for the package. Cargo's default behaviour is to merge features for a single package. Let's say you had a dependency called `foo` with features A and B, which was being used by packages `bar` and `baz`, but `bar` depends on `foo+A` and `baz` depends on `foo+B`. Cargo will merge both of those features and compile `foo` as `foo+AB`. This has a benefit that you only have to compile `foo` once, and then it can reused for both `foo` and `bar`.
96+
97+
Dependency management is a hard problem, and one of the hardest parts of it is just picking what *version* of a dependency to use when it's depended on by two different packages. This doesn't just include its version number, but also what features are or aren't enabled for the package. Cargo's default behaviour is to merge features for a single package when it's referred to multiple times in the dependency graph.
98+
99+
For example, let's say you had a dependency called `foo` with features A and B, which was being used by packages `bar` and `baz`, but `bar` depends on `foo+A` and `baz` depends on `foo+B`. Cargo will merge both of those features and compile `foo` as `foo+AB`. This has a benefit that you only have to compile `foo` once, and then it can reused for both `foo` and `bar`.
109100

110101
However, this also comes with a downside. What if `A` and `B` are incompatible? What if your own code is compatible with `foo` but not `foo+A`? A common example of this in the ecosystem is the optional `std` feature included in many `#![no_std]` crates, that allows crates to provide added functionality when `std` is available. Now imagine you want to use the `#![no_std]` version of `foo` in your `#![no_std]` binary, and use the `foo` at build time in your `build.rs`. If your build time dependency depends on `foo+std`, your binary now also depends on `foo+std`, which means it will no longer compile because `std` is not available for your target platform.
111102

@@ -115,7 +106,7 @@ This has been a long-standing issue in cargo, and with this release there's a ne
115106
- **Host Dependencies** — When a package is shared as a normal dependency and a build-dependency or proc-macro, the features for the normal dependency are kept independent of the build-dependency or proc-macro.
116107
- **Target dependencies** — When a package appears multiple times in the build graph, and one of those instances is a target-specific dependency, then the features of the target-specific dependency are only enabled if the target is currently being built.
117108

118-
While this can lead to some crates compiling more than once, this should provide a much more intuitive development experience when using features with cargo. If you'd like to know more, you can also read the ["Feature Resolver"][feature-resolver@2.0] section in the Cargo Book for more information. We'd like to thank the cargo team and everyone involved for all their hard work in designing and implementing this new feature (resolver)!
109+
While this can lead to some crates compiling more than once, this should provide a much more intuitive development experience when using features with cargo. If you'd like to know more, you can also read the ["Feature Resolver"][feature-resolver@2.0] section in the Cargo Book for more information. We'd like to thank the cargo team and everyone involved for all their hard work in designing and implementing the new resolver!
119110

120111
```toml
121112
[package]
@@ -129,11 +120,11 @@ resolver = "2"
129120
[feature-resolver@2.0]: https://doc.rust-lang.org/nightly/cargo/reference/features.html#feature-resolver-version-2
130121

131122
### Splitting Debug Information
132-
While not often highlighted in the release, the Rust teams are constantly working on improving Rust's compile times, and this release marks one of the largest improvements in a long time for Rust on macOS platforms. Debug information is code that maps the binary code back to your source code, so that the program can give you more information about what went wrong at runtime. In macOS, debug info is typically collected using a tool called `dsymutil` which places all the debug information into a single `.dSYM` folder.
123+
While not often highlighted in the release, the Rust teams are constantly working on improving Rust's compile times, and this release marks one of the largest improvements in a long time for Rust on macOS. Debug information maps the binary code back to your source code, so that the program can give you more information about what went wrong at runtime. In macOS, debug info was previously collected into a single `.dSYM` folder using a tool called `dsymutil`, which can take some time and use up quite a bit of disk space.
133124

134-
This tool provides a lot of benefits, however, one of the drawbacks has been that `dsymutil` is not really compatible with incremental recompilation. This means that even when you make a small change such as a function name, `dsymutil` will need to run over the entire final binary to produce the final `.dSYM` folder. This can sometimes add a lot to the build time, especially for larger projects, as each dependency needs to be recollected, but this has been a necessary step as without it Rust wouldn't be able to load the debug info on macOS.
125+
Collecting all of the debuginfo into this directory helps in finding it at runtime, particularly if the binary is being moved. However, it does have the drawback that even when you make a small change to your program, `dsymutil` will need to run over the entire final binary to produce the final `.dSYM` folder. This can sometimes add a lot to the build time, especially for larger projects, as all dependencies always get recollected, but this has been a necessary step as without it Rust's standard library didn't know how to load the debug info on macOS.
135126

136-
Recently, Rust backtraces switched to using a different backend which supports loading debuginfo without needing to run `dsymutil`. This can significantly speed up builds that include debuginfo and significantly reduce the amount of disk space used. We haven't run extensive benchmarks but have seen a lot of reports of people's builds being a lot faster on macOS with this behavior.
127+
Recently, Rust backtraces switched to using a different backend which supports loading debuginfo without needing to run `dsymutil`, and we've stabilized support for skipping the `dsymutil` run. This can significantly speed up builds that include debuginfo and significantly reduce the amount of disk space used. We haven't run extensive benchmarks, but have seen a lot of reports of people's builds being a lot faster on macOS with this behavior.
137128

138129
You can enable this new behaviour by setting the `-Csplit-debuginfo=unpacked` flag when running `rustc`, or by setting the [`split-debuginfo`] `[profile]` option to `unpacked` in Cargo. The "unpacked" option instructs rustc to leave the .o object files in the build output directory instead of deleting them, and skips the step of running dsymutil. Rust's backtrace support is smart enough to know how to find these .o files. Tools such as lldb also know how to do this. This should work as long as you don't need to move the binary to a different location while retaining the debug information.
139130

0 commit comments

Comments
 (0)