Skip to content

Commit 7ef73ce

Browse files
committed
New section of the book: nightly rust
Now that feature flags are only on nightly, it's good to split this stuff out.
1 parent a923278 commit 7ef73ce

12 files changed

+542
-597
lines changed

src/doc/trpl/README.md

+8-3
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,12 @@ and will be able to understand most Rust code and write more complex programs.
2929

3030
In a similar fashion to "Intermediate," this section is full of individual,
3131
deep-dive chapters, which stand alone and can be read in any order. These
32-
chapters focus on the most complex features, as well as some things that
33-
are only available in upcoming versions of Rust.
32+
chapters focus on the most complex features,
3433

35-
After reading "Advanced," you'll be a Rust expert!
34+
<h2 class="section-header"><a href="unstable.html">Unstable</a></h2>
35+
36+
In a similar fashion to "Intermediate," this section is full of individual,
37+
deep-dive chapters, which stand alone and can be read in any order.
38+
39+
This chapter contains things that are only available on the nightly channel of
40+
Rust.

src/doc/trpl/SUMMARY.md

+6
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,12 @@
3636
* [FFI](ffi.md)
3737
* [Unsafe Code](unsafe.md)
3838
* [Advanced Macros](advanced-macros.md)
39+
* [Unstable Rust](unstable.md)
3940
* [Compiler Plugins](plugins.md)
41+
* [Inline Assembly](inline-assembly.md)
42+
* [No stdlib](no-stdlib.md)
43+
* [Intrinsics](intrinsics.md)
44+
* [Lang items](lang-items.md)
45+
* [Link args](link-args.md)
4046
* [Conclusion](conclusion.md)
4147
* [Glossary](glossary.md)

src/doc/trpl/advanced-macros.md

-9
Original file line numberDiff line numberDiff line change
@@ -206,8 +206,6 @@ the [Bitwise Cyclic Tag](http://esolangs.org/wiki/Bitwise_Cyclic_Tag) automaton
206206
within Rust's macro system.
207207

208208
```rust
209-
#![feature(trace_macros)]
210-
211209
macro_rules! bct {
212210
// cmd 0: d ... => ...
213211
(0, $($ps:tt),* ; $_d:tt)
@@ -229,13 +227,6 @@ macro_rules! bct {
229227
( $($ps:tt),* ; )
230228
=> (());
231229
}
232-
233-
fn main() {
234-
trace_macros!(true);
235-
# /* just check the definition
236-
bct!(0, 0, 1, 1, 1 ; 1, 0, 1);
237-
# */
238-
}
239230
```
240231

241232
Exercise: use macros to reduce duplication in the above definition of the

src/doc/trpl/ffi.md

-25
Original file line numberDiff line numberDiff line change
@@ -366,31 +366,6 @@ A few examples of how this model can be used are:
366366
367367
On OSX, frameworks behave with the same semantics as a dynamic library.
368368
369-
## The `link_args` attribute
370-
371-
There is one other way to tell rustc how to customize linking, and that is via
372-
the `link_args` attribute. This attribute is applied to `extern` blocks and
373-
specifies raw flags which need to get passed to the linker when producing an
374-
artifact. An example usage would be:
375-
376-
``` no_run
377-
#![feature(link_args)]
378-
379-
#[link_args = "-foo -bar -baz"]
380-
extern {}
381-
# fn main() {}
382-
```
383-
384-
Note that this feature is currently hidden behind the `feature(link_args)` gate
385-
because this is not a sanctioned way of performing linking. Right now rustc
386-
shells out to the system linker, so it makes sense to provide extra command line
387-
arguments, but this will not always be the case. In the future rustc may use
388-
LLVM directly to link native libraries in which case `link_args` will have no
389-
meaning.
390-
391-
It is highly recommended to *not* use this attribute, and rather use the more
392-
formal `#[link(...)]` attribute on `extern` blocks instead.
393-
394369
# Unsafe blocks
395370
396371
Some operations, like dereferencing unsafe pointers or calling functions that have been marked

src/doc/trpl/inline-assembly.md

+141
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
% Inline Assembly
2+
3+
For extremely low-level manipulations and performance reasons, one
4+
might wish to control the CPU directly. Rust supports using inline
5+
assembly to do this via the `asm!` macro. The syntax roughly matches
6+
that of GCC & Clang:
7+
8+
```ignore
9+
asm!(assembly template
10+
: output operands
11+
: input operands
12+
: clobbers
13+
: options
14+
);
15+
```
16+
17+
Any use of `asm` is feature gated (requires `#![feature(asm)]` on the
18+
crate to allow) and of course requires an `unsafe` block.
19+
20+
> **Note**: the examples here are given in x86/x86-64 assembly, but
21+
> all platforms are supported.
22+
23+
## Assembly template
24+
25+
The `assembly template` is the only required parameter and must be a
26+
literal string (i.e. `""`)
27+
28+
```
29+
#![feature(asm)]
30+
31+
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
32+
fn foo() {
33+
unsafe {
34+
asm!("NOP");
35+
}
36+
}
37+
38+
// other platforms
39+
#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
40+
fn foo() { /* ... */ }
41+
42+
fn main() {
43+
// ...
44+
foo();
45+
// ...
46+
}
47+
```
48+
49+
(The `feature(asm)` and `#[cfg]`s are omitted from now on.)
50+
51+
Output operands, input operands, clobbers and options are all optional
52+
but you must add the right number of `:` if you skip them:
53+
54+
```
55+
# #![feature(asm)]
56+
# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
57+
# fn main() { unsafe {
58+
asm!("xor %eax, %eax"
59+
:
60+
:
61+
: "eax"
62+
);
63+
# } }
64+
```
65+
66+
Whitespace also doesn't matter:
67+
68+
```
69+
# #![feature(asm)]
70+
# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
71+
# fn main() { unsafe {
72+
asm!("xor %eax, %eax" ::: "eax");
73+
# } }
74+
```
75+
76+
## Operands
77+
78+
Input and output operands follow the same format: `:
79+
"constraints1"(expr1), "constraints2"(expr2), ..."`. Output operand
80+
expressions must be mutable lvalues:
81+
82+
```
83+
# #![feature(asm)]
84+
# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
85+
fn add(a: i32, b: i32) -> i32 {
86+
let mut c = 0;
87+
unsafe {
88+
asm!("add $2, $0"
89+
: "=r"(c)
90+
: "0"(a), "r"(b)
91+
);
92+
}
93+
c
94+
}
95+
# #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
96+
# fn add(a: i32, b: i32) -> i32 { a + b }
97+
98+
fn main() {
99+
assert_eq!(add(3, 14159), 14162)
100+
}
101+
```
102+
103+
## Clobbers
104+
105+
Some instructions modify registers which might otherwise have held
106+
different values so we use the clobbers list to indicate to the
107+
compiler not to assume any values loaded into those registers will
108+
stay valid.
109+
110+
```
111+
# #![feature(asm)]
112+
# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
113+
# fn main() { unsafe {
114+
// Put the value 0x200 in eax
115+
asm!("mov $$0x200, %eax" : /* no outputs */ : /* no inputs */ : "eax");
116+
# } }
117+
```
118+
119+
Input and output registers need not be listed since that information
120+
is already communicated by the given constraints. Otherwise, any other
121+
registers used either implicitly or explicitly should be listed.
122+
123+
If the assembly changes the condition code register `cc` should be
124+
specified as one of the clobbers. Similarly, if the assembly modifies
125+
memory, `memory` should also be specified.
126+
127+
## Options
128+
129+
The last section, `options` is specific to Rust. The format is comma
130+
separated literal strings (i.e. `:"foo", "bar", "baz"`). It's used to
131+
specify some extra info about the inline assembly:
132+
133+
Current valid options are:
134+
135+
1. *volatile* - specifying this is analogous to
136+
`__asm__ __volatile__ (...)` in gcc/clang.
137+
2. *alignstack* - certain instructions expect the stack to be
138+
aligned a certain way (i.e. SSE) and specifying this indicates to
139+
the compiler to insert its usual stack alignment code
140+
3. *intel* - use intel syntax instead of the default AT&T.
141+

src/doc/trpl/intrinsics.md

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
% Intrinsics
2+
3+
> **Note**: intrinsics will forever have an unstable interface, it is
4+
> recommended to use the stable interfaces of libcore rather than intrinsics
5+
> directly.
6+
7+
These are imported as if they were FFI functions, with the special
8+
`rust-intrinsic` ABI. For example, if one was in a freestanding
9+
context, but wished to be able to `transmute` between types, and
10+
perform efficient pointer arithmetic, one would import those functions
11+
via a declaration like
12+
13+
```
14+
# #![feature(intrinsics)]
15+
# fn main() {}
16+
17+
extern "rust-intrinsic" {
18+
fn transmute<T, U>(x: T) -> U;
19+
20+
fn offset<T>(dst: *const T, offset: isize) -> *const T;
21+
}
22+
```
23+
24+
As with any other FFI functions, these are always `unsafe` to call.
25+

src/doc/trpl/lang-items.md

+79
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
% Lang items
2+
3+
> **Note**: lang items are often provided by crates in the Rust distribution,
4+
> and lang items themselves have an unstable interface. It is recommended to use
5+
> officially distributed crates instead of defining your own lang items.
6+
7+
The `rustc` compiler has certain pluggable operations, that is,
8+
functionality that isn't hard-coded into the language, but is
9+
implemented in libraries, with a special marker to tell the compiler
10+
it exists. The marker is the attribute `#[lang="..."]` and there are
11+
various different values of `...`, i.e. various different 'lang
12+
items'.
13+
14+
For example, `Box` pointers require two lang items, one for allocation
15+
and one for deallocation. A freestanding program that uses the `Box`
16+
sugar for dynamic allocations via `malloc` and `free`:
17+
18+
```
19+
#![feature(lang_items, box_syntax, start, no_std)]
20+
#![no_std]
21+
22+
extern crate libc;
23+
24+
extern {
25+
fn abort() -> !;
26+
}
27+
28+
#[lang = "owned_box"]
29+
pub struct Box<T>(*mut T);
30+
31+
#[lang="exchange_malloc"]
32+
unsafe fn allocate(size: usize, _align: usize) -> *mut u8 {
33+
let p = libc::malloc(size as libc::size_t) as *mut u8;
34+
35+
// malloc failed
36+
if p as usize == 0 {
37+
abort();
38+
}
39+
40+
p
41+
}
42+
#[lang="exchange_free"]
43+
unsafe fn deallocate(ptr: *mut u8, _size: usize, _align: usize) {
44+
libc::free(ptr as *mut libc::c_void)
45+
}
46+
47+
#[start]
48+
fn main(argc: isize, argv: *const *const u8) -> isize {
49+
let x = box 1;
50+
51+
0
52+
}
53+
54+
#[lang = "stack_exhausted"] extern fn stack_exhausted() {}
55+
#[lang = "eh_personality"] extern fn eh_personality() {}
56+
#[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} }
57+
```
58+
59+
Note the use of `abort`: the `exchange_malloc` lang item is assumed to
60+
return a valid pointer, and so needs to do the check internally.
61+
62+
Other features provided by lang items include:
63+
64+
- overloadable operators via traits: the traits corresponding to the
65+
`==`, `<`, dereferencing (`*`) and `+` (etc.) operators are all
66+
marked with lang items; those specific four are `eq`, `ord`,
67+
`deref`, and `add` respectively.
68+
- stack unwinding and general failure; the `eh_personality`, `fail`
69+
and `fail_bounds_checks` lang items.
70+
- the traits in `std::marker` used to indicate types of
71+
various kinds; lang items `send`, `sync` and `copy`.
72+
- the marker types and variance indicators found in
73+
`std::marker`; lang items `covariant_type`,
74+
`contravariant_lifetime`, etc.
75+
76+
Lang items are loaded lazily by the compiler; e.g. if one never uses
77+
`Box` then there is no need to define functions for `exchange_malloc`
78+
and `exchange_free`. `rustc` will emit an error when an item is needed
79+
but not found in the current crate or any that it depends on.

src/doc/trpl/link-args.md

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
% Link args
2+
3+
There is one other way to tell rustc how to customize linking, and that is via
4+
the `link_args` attribute. This attribute is applied to `extern` blocks and
5+
specifies raw flags which need to get passed to the linker when producing an
6+
artifact. An example usage would be:
7+
8+
``` no_run
9+
#![feature(link_args)]
10+
11+
#[link_args = "-foo -bar -baz"]
12+
extern {}
13+
# fn main() {}
14+
```
15+
16+
Note that this feature is currently hidden behind the `feature(link_args)` gate
17+
because this is not a sanctioned way of performing linking. Right now rustc
18+
shells out to the system linker, so it makes sense to provide extra command line
19+
arguments, but this will not always be the case. In the future rustc may use
20+
LLVM directly to link native libraries in which case `link_args` will have no
21+
meaning.
22+
23+
It is highly recommended to *not* use this attribute, and rather use the more
24+
formal `#[link(...)]` attribute on `extern` blocks instead.
25+

0 commit comments

Comments
 (0)