



















The Rust team is happy to announce the latest version of Rust, 1.17.0. Rust is a systems programming language focused on safety, speed, and concurrency.
If you have a previous version of Rust installed, getting Rust 1.17 is as easy as:
$ rustup update stable
If you don't have it already, you can get rustup from the
appropriate page on our website, and check out the detailed release notes for
1.17.0 on GitHub.
The story of Rust 1.17.0 is mostly one of small, quality of life improvements. For example,
the 'static lifetime is now assumed in statics and consts. When writing a const or static like this:
const NAME: &'static str = "Ferris";
static NAME: &'static str = "Ferris";
Rust 1.17 will allow you to elide the 'static, since that's the only lifetime that makes
sense:
const NAME: &str = "Ferris";
static NAME: &str = "Ferris";
In some situations, this can remove lots of boilerplate:
// old
const NAMES: &'static [&'static str; 2] = &["Ferris", "Bors"];
// new
const NAMES: &[&str; 2] = &["Ferris", "Bors"];
Another similar improvement is "field init shorthand." Similar to ECMAScript 6, which calls this "Object Literal Property Value Shorthand", duplication can be removed when declaring structs, like this:
// definitions
struct Point {
x: i32,
y: i32,
}
let x = 5;
let y = 6;
// old
let p = Point {
x: x,
y: y,
};
// new
let p = Point {
x,
y,
};
That is, the x, y form will assume that its values are set to a variable
with the same name in its scope.
For another small quality of life improvement, it's common for new Rustaceans to
try to use + to add two &strs together. This doesn't work, you can only add
String + &str. As such, a new error
message was added to help users
who make this mistake:
// code
"foo" + "bar"
// old
error[E0369]: binary operation `+` cannot be applied to type `&'static str`
--> <anon>:2:5
|
2 | "foo" + "bar"
| ^^^^^
|
note: an implementation of `std::ops::Add` might be missing for `&'static str`
--> <anon>:2:5
|
2 | "foo" + "bar"
| ^^^^^
// new
error[E0369]: binary operation `+` cannot be applied to type `&'static str`
--> <anon>:2:5
|
2 | "foo" + "bar"
| ^^^^^
|
= note: `+` can't be used to concatenate two `&str` strings
help: to_owned() can be used to create an owned `String` from a string
reference. String concatenation appends the string on the right to the string on
the left and may require reallocation. This requires ownership of the string on
the left.
| "foo".to_owned() + "bar"
When using Cargo's build scripts, you must set the location of the script in your
Cargo.toml. However, the vast majority of people wrote build = "build.rs", using
a build.rs file in the root of their project. This convention is now encoded
into Cargo, and will be assumed if
build.rs exists. We've been warning about this change for the past few releases,
and you can use build = false to opt out.
This release marks the removal
of the old Makefile based build system. The new system, announced in Rust
1.15, is written in Rust and primarily uses Cargo to drive the build. It is now
mature enough to be the only build system.
As part of that change, packages from crates.io can now be used within Rust's build system. The first one to be added was mdBook, and it's now being used to render our various book-like documentation:
In addition, see those links to their respective repositories; they've been moved out of tree. Also, we've added a fourth book, still in-tree: The Unstable Book. This provides an overview of unstable features by name, contains links to their tracking issues, and may contain initial documentation. If there's a feature you want to see stabilized, please get involved on its tracking issue!
A few releases ago, rustup stopped installing documentation
by default. We made this change to save some bandwidth and because not
all users want a copy of the documentation locally. However, this created
a pitfall: some users did not realize that this changed, and would only
notice once they were no longer connected to the internet. In addition,
some users did want to have a local copy of the docs, regardless of
their connectivity. As such, we've reverted the change, and documentation is being
installed by default again.
Finally, while this release is full of improvements, there is one small
step back we want to regretfully inform you about. On Windows, Visual
Studio 2017 has been released, and Microsoft has changed the structure
of how the software is installed. Rust cannot automatically detect this
location, and while we
were working on the necessary changes, they did not make it in time for
this release. Until then, Visual Studio 2015 still works fine, or you
can run vcvars.bat on the command line. We hope to make this work
in a seamless fashion soon.
See the detailed release notes for more.
19 new bits of API were stabilized this release:
Arc::into_raw and Rc::into_raw let you consume an Arc or Rc and get a raw pointer.Arc::from_raw and Rc::from_raw let you take that raw pointer and get an Arc or Rc.Arc::ptr_eq and Rc::ptr_eq return true if the two Arcs or two Rcs point to the same value (not just values that compare as equal).Ordering::then lets you chain two Orderings together, and Ordering::then_with lets you do it with a function.BTreeMap::range allows you to iterate over a portion of a BTreeMap, and BTreeMap::range_mut lets you do it mutably. collections::Bound can give you even more control.process::abort will completely terminate a process in an abnormal fashion.ptr::read_unaligned and ptr::write_unaligned are like ptr::read and ptr::write, but without alignment requirements.Result::expect_err mirrors Result::expect, but with the Err case rather than the Ok case.Cell::swap is similar to std::mem::swap, but lets you do it with &Cell instead of &mut T.Cell::replace is similar to std::mem::replace, but lets you do it with &Cell instead of &mut T.Cell::into_inner lets you consume the Cell, and extract its value.Cell::take lets you take the value out of a Cell, leaving its Default::default behind.In other changes, Cell<T> used to require that T: Copy for many of its methods,
but this has been relaxed significantly.
Box<T> now implements over a dozen new
conversions with From.
SocketAddr and IpAddr have some new conversions
as well. Previously, you may have written code like this:
"127.0.0.1:3000".parse().unwrap()
Now, you can write
SocketAddr::from(([127, 0, 0, 1], 3000))
// or even
([127, 0, 0, 1], 3000).into()
This removes some unnecessary run-time parsing, and is roughly as readable, depending on your preferences.
Backtraces now have nicer formatting, eliding some things by default. For example, the full backtrace:
thread 'main' panicked at 'explicit panic', foo.rs:2
stack backtrace:
1: 0x55c39a23372c - std::sys::imp::backtrace::tracing::imp::write::hf33ae72d0baa11ed
at /buildslave/rust-buildbot/slave/stable-dist-rustc-linux/build/src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:42
2: 0x55c39a23571e - std::panicking::default_hook::{{closure}}::h59672b733cc6a455
at /buildslave/rust-buildbot/slave/stable-dist-rustc-linux/build/src/libstd/panicking.rs:351
3: 0x55c39a235324 - std::panicking::default_hook::h1670459d2f3f8843
at /buildslave/rust-buildbot/slave/stable-dist-rustc-linux/build/src/libstd/panicking.rs:367
4: 0x55c39a235afb - std::panicking::rust_panic_with_hook::hcf0ddb069e7beee7
at /buildslave/rust-buildbot/slave/stable-dist-rustc-linux/build/src/libstd/panicking.rs:555
5: 0x55c39a22e866 - std::panicking::begin_panic::heb433e9aa28a7408
6: 0x55c39a22e9bf - foo::main::hd216d4a160fcce19
7: 0x55c39a23d44a - __rust_maybe_catch_panic
at /buildslave/rust-buildbot/slave/stable-dist-rustc-linux/build/src/libpanic_unwind/lib.rs:98
8: 0x55c39a236006 - std::rt::lang_start::hd7c880a37a646e81
at /buildslave/rust-buildbot/slave/stable-dist-rustc-linux/build/src/libstd/panicking.rs:436
at /buildslave/rust-buildbot/slave/stable-dist-rustc-linux/build/src/libstd/panic.rs:361
at /buildslave/rust-buildbot/slave/stable-dist-rustc-linux/build/src/libstd/rt.rs:57
9: 0x55c39a22e9e9 - main
10: 0x7f5e5ed3382f - __libc_start_main
11: 0x55c39a22e6b8 - _start
12: 0x0 - <unknown>
is now instead
thread 'main' panicked at 'explicit panic', foo.rs:2
stack backtrace:
0: std::sys::imp::backtrace::tracing::imp::unwind_backtrace
at /checkout/src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:49
1: std::sys_common::backtrace::_print
at /checkout/src/libstd/sys_common/backtrace.rs:71
2: std::panicking::default_hook::{{closure}}
at /checkout/src/libstd/sys_common/backtrace.rs:60
at /checkout/src/libstd/panicking.rs:355
3: std::panicking::default_hook
at /checkout/src/libstd/panicking.rs:371
4: std::panicking::rust_panic_with_hook
at /checkout/src/libstd/panicking.rs:549
5: std::panicking::begin_panic
6: foo::main
7: __rust_maybe_catch_panic
at /checkout/src/libpanic_unwind/lib.rs:98
8: std::rt::lang_start
at /checkout/src/libstd/panicking.rs:433
at /checkout/src/libstd/panic.rs:361
at /checkout/src/libstd/rt.rs:57
9: main
10: __libc_start_main
11: _start
By default. You can set the environment variable RUST_BACKTRACE=full to get the full
backtrace. We may be able to do more cleanup in the future; see this bug for more.
See the detailed release notes for more.
Other than the previously mentioned build.rs changes, Cargo has a few new improvements.
cargo check --all and
cargo run --package are two missing
flags that are now supported.
You can now opt in to ignoring SSL revocation checks. The default is still to check, of course.
A new field in Cargo.toml, required-features, lets you specify specific features
that must be set for a target to be built.
Here's an example: let's say that we are writing a crate that interacts with databases,
and that we support multiple databases. We might have this in our Cargo.toml:
[features]
# ...
postgres = []
sqlite = []
tools = []
The tools feature allows us to include extra tooling, and the postgres and sqlite
features control which databases we want to support.
Previously, cargo build would attempt to build all targets, which is normally what
you want. But what if we had a src/bin/postgres-tool.rs, that would only really
be relevant if the postgres and tools features would be enabled? Previously,
we would have to write something like this:
#[cfg(not(all(feature = "postgres", feature = "tools")))]
fn main() {
println!("This tool requires the `postgres` and `tools` features to be enabled.");
}
#[cfg(all(feature = "postgres", feature = "tools"))]
fn main() {
// real code
}
This is a lot of boilerplate to work around cargo build's behavior. It's even
more unfortunate with examples/, which are supposed to show off how to use
your library, but this shenanigans is only relevant within the package, not if
you were to try to use the example on your own.
With the new required-features key, we can add this:
[[bin]]
# ...
required-features = ["postgres", "tools"]
Now, cargo build will only build our postgres-tool if we have the two features
set, and so we can write a normal fn main without all the cfg nonsense getting
in the way.
See the detailed release notes for more.
Many people came together to create Rust 1.17. We couldn't have done it without all of you. Thanks!
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。