Skip to content

Commit c784c7d

Browse files
Merge pull request #281 from rust-lang/1.30-announcement
Rust 1.30
2 parents baee48c + 2680b32 commit c784c7d

File tree

2 files changed

+367
-0
lines changed

2 files changed

+367
-0
lines changed

_posts/2018-10-25-Rust-1.30.0.md

+367
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,367 @@
1+
---
2+
layout: post
3+
title: "Announcing Rust 1.30"
4+
author: The Rust Core Team
5+
---
6+
7+
The Rust team is happy to announce a new version of Rust, 1.30.0. Rust is a
8+
systems programming language focused on safety, speed, and concurrency.
9+
10+
If you have a previous version of Rust installed via rustup, getting Rust
11+
1.30.0 is as easy as:
12+
13+
```bash
14+
$ rustup update stable
15+
```
16+
17+
If you don't have it already, you can [get `rustup`][install] from the
18+
appropriate page on our website, and check out the [detailed release notes for
19+
1.30.0][notes] on GitHub.
20+
21+
[install]: https://www.rust-lang.org/install.html
22+
[notes]: https://github.com./rust-lang/rust/blob/master/RELEASES.md#version-1300-2018-10-25
23+
24+
## What's in 1.30.0 stable
25+
26+
Rust 1.30 is an exciting release with a number of features. On Monday, expect another
27+
blog post asking you to check out Rust 1.31's beta; Rust 1.31 will be the first release
28+
of "Rust 2018." For more on that concept, please see our previous post
29+
["What is Rust 2018"](https://blog.rust-lang.org/2018/07/27/what-is-rust-2018.html).
30+
31+
## Procedural Macros
32+
33+
Way back in [Rust 1.15], we announced the ability to define "custom derives." For example,
34+
with `serde_json`, you could
35+
36+
```rust
37+
#[derive(Serialize, Deserialize, Debug)]
38+
struct Pet {
39+
name: String,
40+
}
41+
```
42+
43+
And convert a `Pet` to and from JSON because `serde_json` defined `Serialize` and
44+
`Deserialize` in a procedural macro.
45+
46+
Rust expands on this by adding the ability to define two other kinds of
47+
advanced macros, "attribute-like procedrual macros" and "function-like
48+
procedural macros."
49+
50+
Attribute-like macros are similar to custom derive macros, but instead of generating code
51+
for only the `#[derive]` attribute, they allow you to create new, custom attributes of
52+
your own. They're also more flexible: derive only works for structs and enums, but
53+
attributes can go on other places, like functions. As an example of using an
54+
attribute-like macro, you might have something like this when using a web application
55+
framework:
56+
57+
```
58+
#[route(GET, "/")]
59+
fn index() {
60+
```
61+
62+
This `#[route]` attribute would be defined by the framework itself, as a
63+
procedural macro. Its signature would look like this:
64+
65+
```
66+
#[proc_macro_attribute]
67+
pub fn route(attr: TokenStream, item: TokenStream) -> TokenStream {
68+
```
69+
70+
Here, we have two input `TokenStreams`: the first is for the contents of the
71+
attribute itself, that is, the `GET, "/"` stuff. The second is the body of the
72+
thing the attribute is attached to, in this case, `fn index() {}` and the rest
73+
of the function's body.
74+
75+
Function-like macros define macros that look like function calls. For
76+
example, an `sql!` macro:
77+
78+
```rust
79+
let sql = sql!(SELECT * FROM posts WHERE id=1);
80+
```
81+
82+
This macro would parse the SQL statement inside of it and check that it's
83+
syntactically correct. This macro would be defined like this:
84+
85+
```
86+
#[proc_macro]
87+
pub fn sql(input: TokenStream) -> TokenStream {
88+
```
89+
90+
This is similar to the derive macro's signature: we get the tokens that
91+
are inside of the parentheses and return the code we want to generate.
92+
93+
### `use` and macros
94+
95+
You can now [bring macros into scope with the `use` keyword][externmacro]. For example,
96+
to use `serde-json`'s `json` macro, you used to write:
97+
98+
```rust
99+
#[macro_use]
100+
extern crate serde_json;
101+
102+
let john = json!({
103+
"name": "John Doe",
104+
"age": 43,
105+
"phones": [
106+
"+44 1234567",
107+
"+44 2345678"
108+
]
109+
});
110+
```
111+
112+
But now, you'd write
113+
114+
```rust
115+
extern crate serde_json;
116+
117+
use serde_json::json;
118+
119+
let john = json!({
120+
"name": "John Doe",
121+
"age": 43,
122+
"phones": [
123+
"+44 1234567",
124+
"+44 2345678"
125+
]
126+
});
127+
```
128+
129+
This brings macros more in line with other items and removes the need for
130+
`macro_use` annotations.
131+
132+
[externmacro]: https://github.com./rust-lang/rust/pull/50911/
133+
[Rust 1.15]: https://blog.rust-lang.org/2017/02/02/Rust-1.15.html
134+
135+
Finally, the [`proc_macro` crate](https://doc.rust-lang.org/stable/proc_macro/)
136+
is made stable, which gives you the needed APIs to write these sorts of macros.
137+
It also has significantly improved the APIs for errors, and crates like `syn` and
138+
`quote` are already using them. For example, before:
139+
140+
```rust,ignore
141+
#[derive(Serialize)]
142+
struct Demo {
143+
ok: String,
144+
bad: std::thread::Thread,
145+
}
146+
```
147+
148+
used to give this error:
149+
150+
```text
151+
error[E0277]: the trait bound `std::thread::Thread: _IMPL_SERIALIZE_FOR_Demo::_serde::Serialize` is not satisfied
152+
--> src/main.rs:3:10
153+
|
154+
3 | #[derive(Serialize)]
155+
| ^^^^^^^^^ the trait `_IMPL_SERIALIZE_FOR_Demo::_serde::Serialize` is not implemented for `std::thread::Thread`
156+
```
157+
158+
Now it will give this one:
159+
160+
```text
161+
error[E0277]: the trait bound `std::thread::Thread: serde::Serialize` is not satisfied
162+
--> src/main.rs:7:5
163+
|
164+
7 | bad: std::thread::Thread,
165+
| ^^^ the trait `serde::Serialize` is not implemented for `std::thread::Thread`
166+
```
167+
168+
## Module system improvements
169+
170+
The module system has long been a pain point of new Rustaceans; several of
171+
its rules felt awkward in practice. These changes are the first steps we're
172+
taking to make the module system feel more straightforward.
173+
174+
There's two changes to `use` in addition to the aforementioned change for
175+
macros. The first is that [external crates are now in the
176+
prelude][nocoloncolon], that is:
177+
178+
```rust
179+
// old
180+
let json = ::serde_json::from_str("...");
181+
182+
// new
183+
let json = serde_json::from_str("...");
184+
```
185+
186+
The trick here is that the 'old' style wasn't always needed, due to the way Rust's
187+
module system worked:
188+
189+
```rust,ignore
190+
extern crate serde_json;
191+
192+
fn main() {
193+
// this works just fine; we're in the crate root, so `serde_json` is in
194+
// scope here
195+
let json = serde_json::from_str("...");
196+
}
197+
198+
mod foo {
199+
fn bar() {
200+
// this doesn't work; we're inside the `foo` namespace, and `serde_json`
201+
// isn't declared there
202+
let json = serde_json::from_str("...");
203+
204+
}
205+
206+
// one option is to `use` it inside the module
207+
use serde_json;
208+
209+
fn baz() {
210+
// the other option is to use `::serde_json`, so we're using an absolute path
211+
// rather than a relative one
212+
let json = ::serde_json::from_str("...");
213+
}
214+
}
215+
```
216+
217+
Moving a function to a submodule and having some of your code break was not a great
218+
experience. Now, it will check the first part of the path and see if it's an `extern
219+
crate`, and if it is, use it regardless of where you're at in the module hierarchy.
220+
221+
[nocoloncolon]: https://github.com./rust-lang/rust/pull/54404/
222+
223+
Finally, [`use` also supports bringing items into scope with paths starting with
224+
`crate`][usecrate]:
225+
226+
```rust
227+
mod foo {
228+
pub fn bar() {
229+
// ...
230+
}
231+
}
232+
233+
// old
234+
use ::foo::bar;
235+
// or
236+
use foo::bar;
237+
238+
// new
239+
use crate::foo::bar;
240+
```
241+
242+
The `crate` keyword at the start of the path indicates that you would like the path to
243+
start at your crate root. Previously, paths specified after `use` would always start at
244+
the crate root, but paths referring to items directly would start at the local path,
245+
meaning the behavior of paths was inconsistent:
246+
247+
```rust
248+
mod foo {
249+
pub fn bar() {
250+
// ...
251+
}
252+
}
253+
254+
mod baz {
255+
pub fn qux() {
256+
// old
257+
::foo::bar();
258+
// does not work, which is different than with `use`:
259+
// foo::bar();
260+
261+
// new
262+
crate::foo::bar();
263+
}
264+
}
265+
```
266+
267+
Once this style becomes widely used, this will hopefully make absolute paths a bit more
268+
clear and remove some of the ugliness of leading `::`.
269+
270+
All of these changes combined lead to a more straightforward understanding of how paths
271+
resolve. Wherever you see a path like `a::b::c` someplace other than a `use` statement,
272+
you can ask:
273+
274+
* Is `a` the name of a crate? Then we're looking for `b::c` inside of it.
275+
* Is `a` the keyword `crate`? Then we're looking for `b::c` from the root of our crate.
276+
* Otherwise, we're looking for `a::b::c` from the current spot in the module hierarchy.
277+
278+
The old behavior of `use` paths always starting from the crate root still applies. But
279+
after making a one-time switch to the new style, these rules will apply uniformly to
280+
paths everywhere, and you'll need to tweak your imports much less when moving code around.
281+
282+
[usecrate]: https://github.com./rust-lang/rust/pull/54404/
283+
284+
## Raw Identifiers
285+
286+
[You can now use keywords as identifiers][rawidents] with some new syntax:
287+
288+
```rust
289+
// define a local variable named `for`
290+
let r#for = true;
291+
292+
// define a function named `for`
293+
fn r#for() {
294+
// ...
295+
}
296+
297+
// call that function
298+
r#for();
299+
```
300+
301+
This doesn't have many use cases today, but will once you are trying to use a Rust 2015
302+
crate with a Rust 2018 project and vice-versa because the set of keywords will be
303+
different in the two editions; we'll explain more in the upcoming blog post about
304+
Rust 2018.
305+
306+
[rawidents]: https://github.com./rust-lang/rust/pull/53236/
307+
308+
## `no_std` applications
309+
310+
Back in Rust 1.6, we announced the [stabilization of `no_std` and
311+
`libcore`](https://blog.rust-lang.org/2016/01/21/Rust-1.6.html) for building
312+
projects without the standard library. There was a twist, though: you could
313+
only build libraries, but not applications.
314+
315+
With Rust 1.30, you can [use the `#[panic_handler]`][panichandler] attribute
316+
to implement panics yourself. This now means that you can build applications,
317+
not just libraries, that don't use the standard library.
318+
319+
[panichandler]: https://github.com./rust-lang/rust/pull/51366/
320+
## Other things
321+
322+
Finally, you can now [match on visibility keywords, like `pub`, in
323+
macros][viskeyword] using the `vis` specifier. Additionally, "tool
324+
attributes" like `#[rustfmt::skip]` [are now
325+
stable](https://github.com./rust-lang/rust/pull/53459/). Tool *lints*
326+
like `#[allow(clippy::something)]` are not yet stable, however.
327+
328+
[viskeyword]: https://github.com./rust-lang/rust/pull/53370/
329+
330+
See the [detailed release notes][notes] for more.
331+
332+
### Library stabilizations
333+
334+
A few new APIs were [stabilized for this
335+
release](https://github.com./rust-lang/rust/blob/master/RELEASES.md#stabilized-apis):
336+
337+
* `Ipv4Addr::{BROADCAST, LOCALHOST, UNSPECIFIED}`
338+
* `Ipv6Addr::{BROADCAST, LOCALHOST, UNSPECIFIED}`
339+
* `Iterator::find_map`
340+
341+
Additionally, the standard library has long had functions like `trim_left` to eliminate
342+
whitespace on one side of some text. However, when considering RTL languages, the meaning
343+
of "right" and "left" gets confusing. As such, we're introducing new names for these
344+
APIs:
345+
346+
* `trim_left` -> `trim_start`
347+
* `trim_right` -> `trim_end`
348+
* `trim_left_matches` -> `trim_start_matches`
349+
* `trim_right_matches` -> `trim_end_matches`
350+
351+
We plan to deprecate (but not remove, of course) the old names in Rust 1.33.
352+
353+
See the [detailed release notes][notes] for more.
354+
355+
### Cargo features
356+
357+
The largest feature of Cargo in this release is that we now [have a progress
358+
bar!](https://github.com./rust-lang/cargo/pull/5995/)
359+
360+
![demo gif](/images/2018-10-25-Rust-1.30/demo.gif)
361+
362+
See the [detailed release notes][notes] for more.
363+
364+
## Contributors to 1.30.0
365+
366+
Many people came together to create Rust 1.30. We couldn't have done it
367+
without all of you. [Thanks!](https://thanks.rust-lang.org/rust/1.30.0)

images/2018-10-25-Rust-1.30/demo.gif

405 KB
Loading

0 commit comments

Comments
 (0)