Skip to content

Commit cfe470c

Browse files
committed
Rust 1.30
1 parent fd108b3 commit cfe470c

File tree

1 file changed

+355
-0
lines changed

1 file changed

+355
-0
lines changed

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

Lines changed: 355 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,355 @@
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.
44+
45+
Rust expands on this by adding the ability to define two other kinds of
46+
advanced macros, "attribute-like procedrual macros" and "function-like
47+
procedural macros."
48+
49+
Attribute-like macros are similar to custom derive macros, but instead of
50+
generating code for `#[derive]`, they allow you to create new, custom
51+
attributes of your own. They're also more flexible; derive only works for
52+
structs and enums; attributes can go on other places as well, like functions.
53+
As an example of using an attribute-like macro, you might have something like
54+
this when using a web application framework:
55+
56+
```
57+
#[route(GET, "/")]
58+
fn index() {
59+
```
60+
61+
This `#[route]` attribute would be defined by the framework itself, as a
62+
procedural macro. Its signature would look like this:
63+
64+
```
65+
#[proc_macro_attribute]
66+
pub fn route(attr: TokenStream, item: TokenStream) -> TokenStream {
67+
```
68+
69+
Here, we have two input `TokenStreams`; the first is for the contents of the
70+
attribute itself, that is, the `GET, "/"` stuff. The second is the body of the
71+
thing the attribute is attached to, in this case, `fn index() {}` and the rest
72+
of the function's body.
73+
74+
Function-like macros define macros that look like function calls. For
75+
example, an `sql!` macro:
76+
77+
```rust
78+
let sql = sql!(SELECT * FROM posts WHERE id=1);
79+
```
80+
81+
This macro would parse the SQL statement inside of it and check that it's
82+
syntactically correct. This macro would be defined like this:
83+
84+
```
85+
#[proc_macro]
86+
pub fn sql(input: TokenStream) -> TokenStream {
87+
```
88+
89+
This is similar to the derive macro's signature: we get in the tokens that
90+
are inside of the parentheses, and return the code we wanted to generate.
91+
92+
### `use` and macros
93+
94+
You can now [use `use` to bring macros into scope][externmacro]. For example,
95+
to use `serde-json`'s `json` macro, you used to write:
96+
97+
```rust
98+
#[macro_use]
99+
extern crate serde_json;
100+
101+
let john = json!({
102+
"name": "John Doe",
103+
"age": 43,
104+
"phones": [
105+
"+44 1234567",
106+
"+44 2345678"
107+
]
108+
});
109+
```
110+
111+
But now, you'd write
112+
113+
```rust
114+
extern crate serde_json;
115+
116+
use serde_json::json;
117+
118+
let john = json!({
119+
"name": "John Doe",
120+
"age": 43,
121+
"phones": [
122+
"+44 1234567",
123+
"+44 2345678"
124+
]
125+
});
126+
```
127+
128+
This brings macros more in line with other items, and removes the need for
129+
`macro_use` annotations.
130+
131+
[externmacro]: https://github.com/rust-lang/rust/pull/50911/
132+
[Rust 1.15]: https://blog.rust-lang.org/2017/02/02/Rust-1.15.html
133+
134+
## Module system improvements
135+
136+
The module system has long been a pain point of new Rustaceans; several of
137+
its rules felt awkward in practice. These changes are the first steps we're
138+
taking to make the module system feel more straightforward.
139+
140+
[`mod.rs` files are now optional][optionalmod]. Imagine we had a `foo`
141+
submodule, with a `bar` submodule of its own. The directory layout would
142+
look like this:
143+
144+
```text
145+
.
146+
├── src
147+
│ ├── foo
148+
│ │ └── mod.rs
149+
│ │ └── bar.rs
150+
│ └── lib.rs
151+
```
152+
153+
In Rust 1.30, you can do this instead:
154+
155+
```text
156+
.
157+
├── src
158+
│ ├── foo
159+
│ │ └── bar.rs
160+
│ ├── foo.rs
161+
│ └── lib.rs
162+
```
163+
164+
This means that you'll no longer have plenty of tabs all named `mod.rs` in
165+
your IDE! It also eases the process of adding a submodule; before `bar`
166+
existed, the project would look like this:
167+
168+
```text
169+
.
170+
├── src
171+
│ ├── foo.rs
172+
│ └── lib.rs
173+
```
174+
175+
Many users found the need to move `foo.rs` into `foo/mod.rs` to be an
176+
unncessary, strage requirement. With the new layout, you create `src/foo` and
177+
put `bar.rs` in it and you're done.
178+
179+
[optionalmod]: https://github.com/rust-lang/rust/pull/54072
180+
181+
There's two changes to `use` as well. Well, three changes: we already
182+
mentioned that you can use `use` to bring macros into scope in the macros
183+
section. There's two more. The first is that you can [`use` an extern crate
184+
without needing `::`][nocoloncolon], that is:
185+
186+
```rust
187+
// old
188+
let json = ::serde_json::from_str("...");
189+
190+
// new
191+
let json = serde_json::from_str("...");
192+
```
193+
194+
The trick here is that the 'old' style wasn't always needed, due to the way Rust's
195+
module system worked:
196+
197+
```rust,ignore
198+
extern crate serde_json;
199+
200+
fn main() {
201+
// this works just fine; we're in the crate root, so `serde_json` is in
202+
// scope here
203+
let json = serde_json::from_str("...");
204+
}
205+
206+
mod foo {
207+
fn bar() {
208+
// this doesn't work; we're inside the `foo` namespace, and `serde_json`
209+
// isn't declared there
210+
let json = serde_json::from_str("...");
211+
212+
}
213+
214+
// one option is to `use` it inside the module
215+
use serde_json;
216+
217+
fn baz() {
218+
// the other option is to use `::serde_json`, so we're using an absolute path rather than
219+
// a relative one
220+
let json = ::serde_json::from_str("...");
221+
}
222+
}
223+
```
224+
225+
Moving a function to a submodule and having your imports break was not a
226+
great experience. Now, `use` will check to see if the first part of the path
227+
and see if it's one of your `extern crate`s, and if it is, use it, regardless
228+
of where you're at in the module hierarchy.
229+
230+
[nocoloncolon]: https://github.com/rust-lang/rust/pull/54404/
231+
232+
Finally, you can also [use `crate` with `use`][usecrate]:
233+
234+
```rust
235+
mod foo {
236+
pub fn bar() {
237+
// ...
238+
}
239+
}
240+
241+
// old
242+
use ::foo::bar;
243+
244+
// new
245+
use crate::foo::bar;
246+
```
247+
248+
The `crate` keyword at the start of the path indicates that you would like
249+
the path to start at your crate root. `use` previously would always start at
250+
the crate root, but other paths would start at the local path, meaning:
251+
252+
```rust
253+
mod foo {
254+
pub fn bar() {
255+
// ...
256+
}
257+
}
258+
259+
mod baz {
260+
pub fn qux() {
261+
// old
262+
::foo::bar();
263+
264+
// new
265+
crate::foo::bar();
266+
}
267+
}
268+
```
269+
270+
This will hopefully make absolute paths a bit more clear, and remove some of
271+
the ugliness of leading `::`.
272+
273+
All of these changes combined lead to a more straightforward understanding of
274+
how paths resolve. When you see a path like `a::b::c`, you can ask:
275+
276+
* Is `a` the name of a crate? Then we're looking for `b::c` inside of it.
277+
* Is `a` the keyword `crate`? Then we're looking for `b::c` from the root of our crate.
278+
* Otherwise, we're looking for `a::b::c` from the current spot in the module hierarchy.
279+
280+
Since these rules apply uniformly everywhere, you'll need to tweak your
281+
imports much less when moving code around.
282+
283+
[usecrate]: https://github.com/rust-lang/rust/pull/54404/
284+
285+
## Raw Identifiers
286+
287+
[You can now use keywords as identifiers][rawidents] with some new syntax:
288+
289+
```rust
290+
// define a local variable named `for`
291+
let r#for = true;
292+
293+
// define a function named `for`
294+
fn r#for() {
295+
// ...
296+
}
297+
298+
// call that function
299+
r#for();
300+
```
301+
302+
This doesn't have many use cases today, but will once you are trying to use a
303+
Rust 2015 crate with a Rust 2018 project, and vice-versa; we'll explain more
304+
in that upcoming blog post.
305+
306+
[rawidents]: https://github.com/rust-lang/rust/pull/53236/
307+
308+
## Other things
309+
310+
Finally, you can [use the `#[panic_handler]`][panichandler] attribute to
311+
implement panics yourself, and you can now [match on visibility keywords,
312+
like `pub`, in macros][viskeyword] using the `vis` specifier.
313+
314+
[panichandler]: https://github.com/rust-lang/rust/pull/51366/
315+
[viskeyword]: https://github.com/rust-lang/rust/pull/53370/
316+
317+
See the [detailed release notes][notes] for more.
318+
319+
### Library stabilizations
320+
321+
A few new APIs were [stabilized for this
322+
release](https://github.com/rust-lang/rust/blob/master/RELEASES.md#stabilized-apis):
323+
324+
* `Ipv4Addr::{BROADCAST, LOCALHOST, UNSPECIFIED}`
325+
* `Ipv6Addr::{BROADCAST, LOCALHOST, UNSPECIFIED}`
326+
* `Iterator::find_map`
327+
328+
Additionally, the standard library has long had functions like `trim_left` to eliminate
329+
whitespace on one side of some text. However, when considering RTL languages, the meaning
330+
of "right" and "left" get confusing. As such, we're introducing some new names for these
331+
APIs:
332+
333+
* `trim_left` -> `trim_start`
334+
* `trim_right` -> `trim_end`
335+
* `trim_left_matches` -> `trim_start_matches`
336+
* `trim_right_matches` -> `trim_end_matches`
337+
338+
We plan to deprecate (but not removing, of course) the old names in Rust
339+
1.33.
340+
341+
See the [detailed release notes][notes] for more.
342+
343+
### Cargo features
344+
345+
The largest feature of Cargo in this release is that we now [have a progress
346+
bar!](https://github.com/rust-lang/cargo/pull/5995/)
347+
348+
> GIF goes here
349+
350+
See the [detailed release notes][notes] for more.
351+
352+
## Contributors to 1.30.0
353+
354+
Many people came together to create Rust 1.30. We couldn't have done it
355+
without all of you. [Thanks!](https://thanks.rust-lang.org/rust/1.30.0)

0 commit comments

Comments
 (0)