Auto merge of #39866 - steveklabnik:unstable-book, r=alexcrichton
Create the Unstable Book Part of https://github.com/rust-lang/rust/issues/39588 This isn't done yet. To do: - [x] import the nightly book contents here - [ ] possibly write some more chapters This will _not_ be done before it lands; that's part of the whole unstable thing.
This commit is contained in:
commit
bfe45974a1
@ -577,6 +577,15 @@ pub fn build_rules<'a>(build: &'a Build) -> Rules {
|
||||
})
|
||||
.default(build.config.docs)
|
||||
.run(move |s| doc::rustbook(build, s.target, "reference"));
|
||||
rules.doc("doc-unstable-book", "src/doc/unstable-book")
|
||||
.dep(move |s| {
|
||||
s.name("tool-rustbook")
|
||||
.host(&build.config.build)
|
||||
.target(&build.config.build)
|
||||
.stage(0)
|
||||
})
|
||||
.default(build.config.docs)
|
||||
.run(move |s| doc::rustbook(build, s.target, "unstable-book"));
|
||||
rules.doc("doc-standalone", "src/doc")
|
||||
.dep(move |s| {
|
||||
s.name("rustc")
|
||||
|
@ -21,7 +21,6 @@ is the first. After this:
|
||||
* [Tutorial: Guessing Game][gg] - Learn some Rust with a small project.
|
||||
* [Syntax and Semantics][ss] - Each bit of Rust, broken down into small chunks.
|
||||
* [Effective Rust][er] - Higher-level concepts for writing excellent Rust code.
|
||||
* [Nightly Rust][nr] - Cutting-edge features that aren’t in stable builds yet.
|
||||
* [Glossary][gl] - A reference of terms used in the book.
|
||||
* [Bibliography][bi] - Background on Rust's influences, papers about Rust.
|
||||
|
||||
@ -29,7 +28,6 @@ is the first. After this:
|
||||
[gg]: guessing-game.html
|
||||
[er]: effective-rust.html
|
||||
[ss]: syntax-and-semantics.html
|
||||
[nr]: nightly-rust.html
|
||||
[gl]: glossary.html
|
||||
[bi]: bibliography.html
|
||||
|
||||
|
@ -55,18 +55,6 @@
|
||||
* [Release Channels](release-channels.md)
|
||||
* [Using Rust without the standard library](using-rust-without-the-standard-library.md)
|
||||
* [Procedural Macros (and custom derive)](procedural-macros.md)
|
||||
* [Nightly Rust](nightly-rust.md)
|
||||
* [Compiler Plugins](compiler-plugins.md)
|
||||
* [Inline Assembly](inline-assembly.md)
|
||||
* [No stdlib](no-stdlib.md)
|
||||
* [Intrinsics](intrinsics.md)
|
||||
* [Lang items](lang-items.md)
|
||||
* [Advanced linking](advanced-linking.md)
|
||||
* [Benchmark Tests](benchmark-tests.md)
|
||||
* [Box Syntax and Patterns](box-syntax-and-patterns.md)
|
||||
* [Slice Patterns](slice-patterns.md)
|
||||
* [Associated Constants](associated-constants.md)
|
||||
* [Custom Allocators](custom-allocators.md)
|
||||
* [Glossary](glossary.md)
|
||||
* [Syntax Index](syntax-index.md)
|
||||
* [Bibliography](bibliography.md)
|
||||
|
@ -1,145 +0,0 @@
|
||||
# Advanced Linking
|
||||
|
||||
The common cases of linking with Rust have been covered earlier in this book,
|
||||
but supporting the range of linking possibilities made available by other
|
||||
languages is important for Rust to achieve seamless interaction with native
|
||||
libraries.
|
||||
|
||||
# Link args
|
||||
|
||||
There is one other way to tell `rustc` how to customize linking, and that is via
|
||||
the `link_args` attribute. This attribute is applied to `extern` blocks and
|
||||
specifies raw flags which need to get passed to the linker when producing an
|
||||
artifact. An example usage would be:
|
||||
|
||||
```rust,no_run
|
||||
#![feature(link_args)]
|
||||
|
||||
#[link_args = "-foo -bar -baz"]
|
||||
extern {}
|
||||
# fn main() {}
|
||||
```
|
||||
|
||||
Note that this feature is currently hidden behind the `feature(link_args)` gate
|
||||
because this is not a sanctioned way of performing linking. Right now `rustc`
|
||||
shells out to the system linker (`gcc` on most systems, `link.exe` on MSVC),
|
||||
so it makes sense to provide extra command line
|
||||
arguments, but this will not always be the case. In the future `rustc` may use
|
||||
LLVM directly to link native libraries, in which case `link_args` will have no
|
||||
meaning. You can achieve the same effect as the `link_args` attribute with the
|
||||
`-C link-args` argument to `rustc`.
|
||||
|
||||
It is highly recommended to *not* use this attribute, and rather use the more
|
||||
formal `#[link(...)]` attribute on `extern` blocks instead.
|
||||
|
||||
# Static linking
|
||||
|
||||
Static linking refers to the process of creating output that contains all
|
||||
required libraries and so doesn't need libraries installed on every system where
|
||||
you want to use your compiled project. Pure-Rust dependencies are statically
|
||||
linked by default so you can use created binaries and libraries without
|
||||
installing Rust everywhere. By contrast, native libraries
|
||||
(e.g. `libc` and `libm`) are usually dynamically linked, but it is possible to
|
||||
change this and statically link them as well.
|
||||
|
||||
Linking is a very platform-dependent topic, and static linking may not even be
|
||||
possible on some platforms! This section assumes some basic familiarity with
|
||||
linking on your platform of choice.
|
||||
|
||||
## Linux
|
||||
|
||||
By default, all Rust programs on Linux will link to the system `libc` along with
|
||||
a number of other libraries. Let's look at an example on a 64-bit Linux machine
|
||||
with GCC and `glibc` (by far the most common `libc` on Linux):
|
||||
|
||||
```text
|
||||
$ cat example.rs
|
||||
fn main() {}
|
||||
$ rustc example.rs
|
||||
$ ldd example
|
||||
linux-vdso.so.1 => (0x00007ffd565fd000)
|
||||
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fa81889c000)
|
||||
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fa81867e000)
|
||||
librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007fa818475000)
|
||||
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fa81825f000)
|
||||
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fa817e9a000)
|
||||
/lib64/ld-linux-x86-64.so.2 (0x00007fa818cf9000)
|
||||
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fa817b93000)
|
||||
```
|
||||
|
||||
Dynamic linking on Linux can be undesirable if you wish to use new library
|
||||
features on old systems or target systems which do not have the required
|
||||
dependencies for your program to run.
|
||||
|
||||
Static linking is supported via an alternative `libc`, [`musl`](http://www.musl-libc.org). You can compile
|
||||
your own version of Rust with `musl` enabled and install it into a custom
|
||||
directory with the instructions below:
|
||||
|
||||
```text
|
||||
$ mkdir musldist
|
||||
$ PREFIX=$(pwd)/musldist
|
||||
$
|
||||
$ # Build musl
|
||||
$ curl -O http://www.musl-libc.org/releases/musl-1.1.10.tar.gz
|
||||
$ tar xf musl-1.1.10.tar.gz
|
||||
$ cd musl-1.1.10/
|
||||
musl-1.1.10 $ ./configure --disable-shared --prefix=$PREFIX
|
||||
musl-1.1.10 $ make
|
||||
musl-1.1.10 $ make install
|
||||
musl-1.1.10 $ cd ..
|
||||
$ du -h musldist/lib/libc.a
|
||||
2.2M musldist/lib/libc.a
|
||||
$
|
||||
$ # Build libunwind.a
|
||||
$ curl -O http://llvm.org/releases/3.7.0/llvm-3.7.0.src.tar.xz
|
||||
$ tar xf llvm-3.7.0.src.tar.xz
|
||||
$ cd llvm-3.7.0.src/projects/
|
||||
llvm-3.7.0.src/projects $ curl http://llvm.org/releases/3.7.0/libunwind-3.7.0.src.tar.xz | tar xJf -
|
||||
llvm-3.7.0.src/projects $ mv libunwind-3.7.0.src libunwind
|
||||
llvm-3.7.0.src/projects $ mkdir libunwind/build
|
||||
llvm-3.7.0.src/projects $ cd libunwind/build
|
||||
llvm-3.7.0.src/projects/libunwind/build $ cmake -DLLVM_PATH=../../.. -DLIBUNWIND_ENABLE_SHARED=0 ..
|
||||
llvm-3.7.0.src/projects/libunwind/build $ make
|
||||
llvm-3.7.0.src/projects/libunwind/build $ cp lib/libunwind.a $PREFIX/lib/
|
||||
llvm-3.7.0.src/projects/libunwind/build $ cd ../../../../
|
||||
$ du -h musldist/lib/libunwind.a
|
||||
164K musldist/lib/libunwind.a
|
||||
$
|
||||
$ # Build musl-enabled rust
|
||||
$ git clone https://github.com/rust-lang/rust.git muslrust
|
||||
$ cd muslrust
|
||||
muslrust $ ./configure --target=x86_64-unknown-linux-musl --musl-root=$PREFIX --prefix=$PREFIX
|
||||
muslrust $ make
|
||||
muslrust $ make install
|
||||
muslrust $ cd ..
|
||||
$ du -h musldist/bin/rustc
|
||||
12K musldist/bin/rustc
|
||||
```
|
||||
|
||||
You now have a build of a `musl`-enabled Rust! Because we've installed it to a
|
||||
custom prefix we need to make sure our system can find the binaries and appropriate
|
||||
libraries when we try and run it:
|
||||
|
||||
```text
|
||||
$ export PATH=$PREFIX/bin:$PATH
|
||||
$ export LD_LIBRARY_PATH=$PREFIX/lib:$LD_LIBRARY_PATH
|
||||
```
|
||||
|
||||
Let's try it out!
|
||||
|
||||
```text
|
||||
$ echo 'fn main() { println!("hi!"); panic!("failed"); }' > example.rs
|
||||
$ rustc --target=x86_64-unknown-linux-musl example.rs
|
||||
$ ldd example
|
||||
not a dynamic executable
|
||||
$ ./example
|
||||
hi!
|
||||
thread 'main' panicked at 'failed', example.rs:1
|
||||
```
|
||||
|
||||
Success! This binary can be copied to almost any Linux machine with the same
|
||||
machine architecture and run without issues.
|
||||
|
||||
`cargo build` also permits the `--target` option so you should be able to build
|
||||
your crates as normal. However, you may need to recompile your native libraries
|
||||
against `musl` before they can be linked against.
|
@ -1,100 +0,0 @@
|
||||
# Box Syntax and Patterns
|
||||
|
||||
Currently the only stable way to create a `Box` is via the `Box::new` method.
|
||||
Also it is not possible in stable Rust to destructure a `Box` in a match
|
||||
pattern. The unstable `box` keyword can be used to both create and destructure
|
||||
a `Box`. An example usage would be:
|
||||
|
||||
```rust
|
||||
#![feature(box_syntax, box_patterns)]
|
||||
|
||||
fn main() {
|
||||
let b = Some(box 5);
|
||||
match b {
|
||||
Some(box n) if n < 0 => {
|
||||
println!("Box contains negative number {}", n);
|
||||
},
|
||||
Some(box n) if n >= 0 => {
|
||||
println!("Box contains non-negative number {}", n);
|
||||
},
|
||||
None => {
|
||||
println!("No box");
|
||||
},
|
||||
_ => unreachable!()
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Note that these features are currently hidden behind the `box_syntax` (box
|
||||
creation) and `box_patterns` (destructuring and pattern matching) gates
|
||||
because the syntax may still change in the future.
|
||||
|
||||
# Returning Pointers
|
||||
|
||||
In many languages with pointers, you'd return a pointer from a function
|
||||
so as to avoid copying a large data structure. For example:
|
||||
|
||||
```rust
|
||||
struct BigStruct {
|
||||
one: i32,
|
||||
two: i32,
|
||||
// Etc.
|
||||
one_hundred: i32,
|
||||
}
|
||||
|
||||
fn foo(x: Box<BigStruct>) -> Box<BigStruct> {
|
||||
Box::new(*x)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x = Box::new(BigStruct {
|
||||
one: 1,
|
||||
two: 2,
|
||||
one_hundred: 100,
|
||||
});
|
||||
|
||||
let y = foo(x);
|
||||
}
|
||||
```
|
||||
|
||||
The idea is that by passing around a box, you're only copying a pointer, rather
|
||||
than the hundred `i32`s that make up the `BigStruct`.
|
||||
|
||||
This is an antipattern in Rust. Instead, write this:
|
||||
|
||||
```rust
|
||||
#![feature(box_syntax)]
|
||||
|
||||
struct BigStruct {
|
||||
one: i32,
|
||||
two: i32,
|
||||
// Etc.
|
||||
one_hundred: i32,
|
||||
}
|
||||
|
||||
fn foo(x: Box<BigStruct>) -> BigStruct {
|
||||
*x
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x = Box::new(BigStruct {
|
||||
one: 1,
|
||||
two: 2,
|
||||
one_hundred: 100,
|
||||
});
|
||||
|
||||
let y: Box<BigStruct> = box foo(x);
|
||||
}
|
||||
```
|
||||
|
||||
This gives you flexibility without sacrificing performance.
|
||||
|
||||
You may think that this gives us terrible performance: return a value and then
|
||||
immediately box it up ?! Isn't this pattern the worst of both worlds? Rust is
|
||||
smarter than that. There is no copy in this code. `main` allocates enough room
|
||||
for the `box`, passes a pointer to that memory into `foo` as `x`, and then
|
||||
`foo` writes the value straight into the `Box<T>`.
|
||||
|
||||
This is important enough that it bears repeating: pointers are not for
|
||||
optimizing returning values from your code. Allow the caller to choose how they
|
||||
want to use your output.
|
@ -151,12 +151,9 @@ elements of the array. These kinds of casts are very dangerous, because they
|
||||
make assumptions about the way that multiple underlying structures are
|
||||
implemented. For this, we need something more dangerous.
|
||||
|
||||
The `transmute` function is provided by a [compiler intrinsic][intrinsics], and
|
||||
what it does is very simple, but very scary. It tells Rust to treat a value of
|
||||
one type as though it were another type. It does this regardless of the
|
||||
typechecking system, and completely trusts you.
|
||||
|
||||
[intrinsics]: intrinsics.html
|
||||
The `transmute` function is very simple, but very scary. It tells Rust to treat
|
||||
a value of one type as though it were another type. It does this regardless of
|
||||
the typechecking system, and completely trusts you.
|
||||
|
||||
In our previous example, we know that an array of four `u8`s represents a `u32`
|
||||
properly, and so we want to do the cast. Using `transmute` instead of `as`,
|
||||
|
@ -79,8 +79,7 @@ Will be the same as `#[b]` if `a` is set by `cfg` attribute, and nothing otherwi
|
||||
|
||||
# cfg!
|
||||
|
||||
The `cfg!` [syntax extension][compilerplugins] lets you use these kinds of flags
|
||||
elsewhere in your code, too:
|
||||
The `cfg!` macro lets you use these kinds of flags elsewhere in your code, too:
|
||||
|
||||
```rust
|
||||
if cfg!(target_os = "macos") || cfg!(target_os = "ios") {
|
||||
@ -88,7 +87,5 @@ if cfg!(target_os = "macos") || cfg!(target_os = "ios") {
|
||||
}
|
||||
```
|
||||
|
||||
[compilerplugins]: compiler-plugins.html
|
||||
|
||||
These will be replaced by a `true` or `false` at compile-time, depending on the
|
||||
configuration settings.
|
||||
|
@ -1,84 +0,0 @@
|
||||
# Lang items
|
||||
|
||||
> **Note**: lang items are often provided by crates in the Rust distribution,
|
||||
> and lang items themselves have an unstable interface. It is recommended to use
|
||||
> officially distributed crates instead of defining your own lang items.
|
||||
|
||||
The `rustc` compiler has certain pluggable operations, that is,
|
||||
functionality that isn't hard-coded into the language, but is
|
||||
implemented in libraries, with a special marker to tell the compiler
|
||||
it exists. The marker is the attribute `#[lang = "..."]` and there are
|
||||
various different values of `...`, i.e. various different 'lang
|
||||
items'.
|
||||
|
||||
For example, `Box` pointers require two lang items, one for allocation
|
||||
and one for deallocation. A freestanding program that uses the `Box`
|
||||
sugar for dynamic allocations via `malloc` and `free`:
|
||||
|
||||
```rust,ignore
|
||||
#![feature(lang_items, box_syntax, start, libc, core_intrinsics)]
|
||||
#![no_std]
|
||||
use core::intrinsics;
|
||||
|
||||
extern crate libc;
|
||||
|
||||
#[lang = "owned_box"]
|
||||
pub struct Box<T>(*mut T);
|
||||
|
||||
#[lang = "exchange_malloc"]
|
||||
unsafe fn allocate(size: usize, _align: usize) -> *mut u8 {
|
||||
let p = libc::malloc(size as libc::size_t) as *mut u8;
|
||||
|
||||
// Check if `malloc` failed:
|
||||
if p as usize == 0 {
|
||||
intrinsics::abort();
|
||||
}
|
||||
|
||||
p
|
||||
}
|
||||
|
||||
#[lang = "exchange_free"]
|
||||
unsafe fn deallocate(ptr: *mut u8, _size: usize, _align: usize) {
|
||||
libc::free(ptr as *mut libc::c_void)
|
||||
}
|
||||
|
||||
#[lang = "box_free"]
|
||||
unsafe fn box_free<T: ?Sized>(ptr: *mut T) {
|
||||
deallocate(ptr as *mut u8, ::core::mem::size_of_val(&*ptr), ::core::mem::align_of_val(&*ptr));
|
||||
}
|
||||
|
||||
#[start]
|
||||
fn main(argc: isize, argv: *const *const u8) -> isize {
|
||||
let x = box 1;
|
||||
|
||||
0
|
||||
}
|
||||
|
||||
#[lang = "eh_personality"] extern fn rust_eh_personality() {}
|
||||
#[lang = "panic_fmt"] extern fn rust_begin_panic() -> ! { unsafe { intrinsics::abort() } }
|
||||
# #[lang = "eh_unwind_resume"] extern fn rust_eh_unwind_resume() {}
|
||||
# #[no_mangle] pub extern fn rust_eh_register_frames () {}
|
||||
# #[no_mangle] pub extern fn rust_eh_unregister_frames () {}
|
||||
```
|
||||
|
||||
Note the use of `abort`: the `exchange_malloc` lang item is assumed to
|
||||
return a valid pointer, and so needs to do the check internally.
|
||||
|
||||
Other features provided by lang items include:
|
||||
|
||||
- overloadable operators via traits: the traits corresponding to the
|
||||
`==`, `<`, dereferencing (`*`) and `+` (etc.) operators are all
|
||||
marked with lang items; those specific four are `eq`, `ord`,
|
||||
`deref`, and `add` respectively.
|
||||
- stack unwinding and general failure; the `eh_personality`,
|
||||
`eh_unwind_resume`, `fail` and `fail_bounds_checks` lang items.
|
||||
- the traits in `std::marker` used to indicate types of
|
||||
various kinds; lang items `send`, `sync` and `copy`.
|
||||
- the marker types and variance indicators found in
|
||||
`std::marker`; lang items `covariant_type`,
|
||||
`contravariant_lifetime`, etc.
|
||||
|
||||
Lang items are loaded lazily by the compiler; e.g. if one never uses
|
||||
`Box` then there is no need to define functions for `exchange_malloc`
|
||||
and `exchange_free`. `rustc` will emit an error when an item is needed
|
||||
but not found in the current crate or any that it depends on.
|
@ -761,12 +761,3 @@ to typecheck, and don’t want to worry about writing out the body of the
|
||||
function. One example of this situation is implementing a trait with multiple
|
||||
required methods, where you want to tackle one at a time. Define the others
|
||||
as `unimplemented!` until you’re ready to write them.
|
||||
|
||||
# Procedural macros
|
||||
|
||||
If Rust’s macro system can’t do what you need, you may want to write a
|
||||
[compiler plugin](compiler-plugins.html) instead. Compared to `macro_rules!`
|
||||
macros, this is significantly more work, the interfaces are much less stable,
|
||||
and bugs can be much harder to track down. In exchange you get the
|
||||
flexibility of running arbitrary Rust code within the compiler. Syntax
|
||||
extension plugins are sometimes called ‘procedural macros’ for this reason.
|
||||
|
@ -1,100 +0,0 @@
|
||||
# Nightly Rust
|
||||
|
||||
Rust provides three distribution channels for Rust: nightly, beta, and stable.
|
||||
Unstable features are only available on nightly Rust. For more details on this
|
||||
process, see [Stability as a deliverable][stability].
|
||||
|
||||
[stability]: http://blog.rust-lang.org/2014/10/30/Stability.html
|
||||
|
||||
To install nightly Rust, you can use [rustup.rs][rustup]:
|
||||
|
||||
[rustup]: https://rustup.rs
|
||||
|
||||
```bash
|
||||
$ curl https://sh.rustup.rs -sSf | sh
|
||||
$ rustup install nightly
|
||||
```
|
||||
|
||||
If you're concerned about the [potential insecurity][insecurity] of using `curl
|
||||
| sh`, please keep reading and see our disclaimer below. And feel free to
|
||||
use a two-step version of the installation and examine our installation script:
|
||||
|
||||
```bash
|
||||
$ curl https://sh.rustup.rs -sSf -o rustup.sh
|
||||
$ sh rustup.sh
|
||||
$ rustup install nightly
|
||||
```
|
||||
|
||||
[insecurity]: http://curlpipesh.tumblr.com
|
||||
|
||||
If you're on Windows, please download the [rustup installer][installer]
|
||||
and run it.
|
||||
|
||||
[installer]: https://win.rustup.rs
|
||||
|
||||
## Uninstalling
|
||||
|
||||
If you decide you don't want Rust anymore, we'll be a bit sad, but that's okay.
|
||||
Not every programming language is great for everyone. Just run the uninstall
|
||||
command:
|
||||
|
||||
```bash
|
||||
$ rustup self uninstall
|
||||
```
|
||||
|
||||
Some people, and somewhat rightfully so, get very upset when we tell you to
|
||||
`curl | sh`. Basically, when you do this, you are trusting that the good
|
||||
people who maintain Rust aren't going to hack your computer and do bad things.
|
||||
That's a good instinct! If you're one of those people, please check out the
|
||||
documentation on [building Rust from Source][from-source], or [the official
|
||||
binary downloads][install-page].
|
||||
|
||||
[from-source]: https://github.com/rust-lang/rust#building-from-source
|
||||
[install-page]: https://www.rust-lang.org/install.html
|
||||
|
||||
Oh, we should also mention the officially supported platforms:
|
||||
|
||||
* Windows (7+)
|
||||
* Linux (2.6.18 or later, various distributions), x86 and x86-64
|
||||
* OSX 10.7 (Lion) or greater, x86 and x86-64
|
||||
|
||||
We extensively test Rust on these platforms, and a few others, too, like
|
||||
Android. But these are the ones most likely to work, as they have the most
|
||||
testing.
|
||||
|
||||
Finally, a comment about Windows. Rust considers Windows to be a first-class
|
||||
platform upon release, but if we're honest, the Windows experience isn't as
|
||||
integrated as the Linux/OS X experience is. We're working on it! If anything
|
||||
does not work, it is a bug. Please let us know if that happens. Each and every
|
||||
commit is tested against Windows like any other platform.
|
||||
|
||||
If you've got Rust installed, you can open up a shell, and type this:
|
||||
|
||||
```bash
|
||||
$ rustc --version
|
||||
```
|
||||
|
||||
You should see the version number, commit hash, commit date and build date:
|
||||
|
||||
```bash
|
||||
rustc 1.0.0-nightly (f11f3e7ba 2015-01-04) (built 2015-01-06)
|
||||
```
|
||||
|
||||
If you did, Rust has been installed successfully! Congrats!
|
||||
|
||||
This installer also installs a copy of the documentation locally, so you can
|
||||
read it offline. On UNIX systems, `/usr/local/share/doc/rust` is the location.
|
||||
On Windows, it's in a `share/doc` directory, inside wherever you installed Rust
|
||||
to.
|
||||
|
||||
If not, there are a number of places where you can get help. The easiest is
|
||||
[the #rust IRC channel on irc.mozilla.org][irc], which you can access through
|
||||
[Mibbit][mibbit]. Click that link, and you'll be chatting with other Rustaceans
|
||||
(a silly nickname we call ourselves), and we can help you out. Other great
|
||||
resources include [the users forum][users], and [Stack Overflow][stackoverflow].
|
||||
|
||||
[irc]: irc://irc.mozilla.org/#rust
|
||||
[mibbit]: http://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust
|
||||
[users]: https://users.rust-lang.org/
|
||||
[stackoverflow]: http://stackoverflow.com/questions/tagged/rust
|
||||
|
@ -139,4 +139,4 @@ I’ll repeat again: even though you _can_ do arbitrary things in unsafe blocks
|
||||
and functions doesn’t mean you should. The compiler will act as though you’re
|
||||
upholding its invariants, so be careful!
|
||||
|
||||
[intrinsics]: intrinsics.html
|
||||
[intrinsics]: ../unstable-book/intrinsics.html
|
||||
|
@ -9,7 +9,7 @@ don’t want to use the standard library via an attribute: `#![no_std]`.
|
||||
> Note: This feature is technically stable, but there are some caveats. For
|
||||
> one, you can build a `#![no_std]` _library_ on stable, but not a _binary_.
|
||||
> For details on binaries without the standard library, see [the nightly
|
||||
> chapter on `#![no_std]`](no-stdlib.html)
|
||||
> chapter on 'lang items'](../unstable-book/lang-items.html#using-libc)
|
||||
|
||||
To use `#![no_std]`, add it to your crate root:
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
% The (old) Rust Compiler Plugins Guide
|
||||
|
||||
This content has moved into
|
||||
[the Rust Programming Language book](book/compiler-plugins.html).
|
||||
[the Unstable Book](unstable-book/plugin.html).
|
||||
|
@ -317,7 +317,7 @@ For any lint check `C`:
|
||||
|
||||
The lint checks supported by the compiler can be found via `rustc -W help`,
|
||||
along with their default settings. [Compiler
|
||||
plugins](../book/compiler-plugins.html#lint-plugins) can provide additional
|
||||
plugins](../unstable-book/plugin.html#lint-plugins) can provide additional
|
||||
lint checks.
|
||||
|
||||
```{.ignore}
|
||||
|
@ -14,4 +14,4 @@ And one unstable way: [compiler plugins].
|
||||
|
||||
[Macros]: ../book/macros.html
|
||||
[Procedural Macros]: ../book/procedural-macros.html
|
||||
[compiler plugins]: ../book/compiler-plugins.html
|
||||
[compiler plugins]: ../unstable-book/plugin.html
|
||||
|
1
src/doc/unstable-book/.gitignore
vendored
Normal file
1
src/doc/unstable-book/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
book
|
94
src/doc/unstable-book/src/SUMMARY.md
Normal file
94
src/doc/unstable-book/src/SUMMARY.md
Normal file
@ -0,0 +1,94 @@
|
||||
[The Unstable Book](the-unstable-book.md)
|
||||
|
||||
- [asm](asm.md)
|
||||
- [alloc_system](alloc-system.md)
|
||||
- [alloc_jemalloc](alloc-jemalloc.md)
|
||||
- [test](test.md)
|
||||
- [concat_idents](concat-idents.md)
|
||||
- [link_args](link-args.md)
|
||||
- [log_syntax](log-syntax.md)
|
||||
- [non_ascii_idents](non-ascii-idents.md)
|
||||
- [plugin_registrar](plugin-registrar.md)
|
||||
- [thread_local](thread-local.md)
|
||||
- [trace_macros](trace-macros.md)
|
||||
- [intrinsics](intrinsics.md)
|
||||
- [lang_items](lang-items.md)
|
||||
- [link_llvm_intrinsics](link-llvm-intrinsics.md)
|
||||
- [linkage](linkage.md)
|
||||
- [quote](quote.md)
|
||||
- [simd](simd.md)
|
||||
- [rustc_diagnostic_macros](rustc-diagnostic-macros.md)
|
||||
- [advanced_slice_patterns](advanced-slice-patterns.md)
|
||||
- [box_syntax](box-syntax.md)
|
||||
- [placement_in_syntax](placement-in-syntax.md)
|
||||
- [unboxed_closures](unboxed-closures.md)
|
||||
- [allocator](allocator.md)
|
||||
- [fundamental](fundamental.md)
|
||||
- [main](main.md)
|
||||
- [needs_allocator](needs-allocator.md)
|
||||
- [on_unimplemented](on-unimplemented.md)
|
||||
- [plugin](plugin.md)
|
||||
- [simd_ffi](simd-ffi.md)
|
||||
- [start](start.md)
|
||||
- [structural_match](structural-match.md)
|
||||
- [panic_runtime](panic-runtime.md)
|
||||
- [needs_panic_runtime](needs-panic-runtime.md)
|
||||
- [optin_builtin_traits](optin-builtin-traits.md)
|
||||
- [macro_reexport](macro-reexport.md)
|
||||
- [staged_api](staged-api.md)
|
||||
- [no_core](no-core.md)
|
||||
- [box_patterns](box-patterns.md)
|
||||
- [dropck_parametricity](dropck-parametricity.md)
|
||||
- [dropck_eyepatch](dropck-eyepatch.md)
|
||||
- [custom_attribute](custom-attribute.md)
|
||||
- [custom_derive](custom-derive.md)
|
||||
- [rustc_attrs](rustc-attrs.md)
|
||||
- [allow_internal_unstable](allow-internal-unstable.md)
|
||||
- [slice_patterns](slice-patterns.md)
|
||||
- [associated_consts](associated-consts.md)
|
||||
- [const_fn](const-fn.md)
|
||||
- [const_indexing](const-indexing.md)
|
||||
- [prelude_import](prelude-import.md)
|
||||
- [static_recursion](static-recursion.md)
|
||||
- [default_type_parameter_fallback](default-type-parameter-fallback.md)
|
||||
- [associated_type_defaults](associated-type-defaults.md)
|
||||
- [repr_simd](repr-simd.md)
|
||||
- [cfg_target_feature](cfg-target-feature.md)
|
||||
- [platform_intrinsics](platform-intrinsics.md)
|
||||
- [unwind_attributes](unwind-attributes.md)
|
||||
- [naked_functions](naked-functions.md)
|
||||
- [no_debug](no-debug.md)
|
||||
- [omit_gdb_pretty_printer_section](omit-gdb-pretty-printer-section.md)
|
||||
- [cfg_target_vendor](cfg-target-vendor.md)
|
||||
- [stmt_expr_attributes](stmt-expr-attributes.md)
|
||||
- [type_ascription](type-ascription.md)
|
||||
- [cfg_target_thread_local](cfg-target-thread-local.md)
|
||||
- [abi_vectorcall](abi-vectorcall.md)
|
||||
- [inclusive_range_syntax](inclusive-range-syntax.md)
|
||||
- [exclusive_range_pattern](exclusive-range-pattern.md)
|
||||
- [specialization](specialization.md)
|
||||
- [pub_restricted](pub-restricted.md)
|
||||
- [drop_types_in_const](drop-types-in-const.md)
|
||||
- [cfg_target_has_atomic](cfg-target-has-atomic.md)
|
||||
- [conservative_impl_trait](conservative-impl-trait.md)
|
||||
- [relaxed_adts](relaxed-adts.md)
|
||||
- [never_type](never-type.md)
|
||||
- [attr_literals](attr-literals.md)
|
||||
- [abi_sysv64](abi-sysv64.md)
|
||||
- [untagged_unions](untagged-unions.md)
|
||||
- [compiler_builtins](compiler-builtins.md)
|
||||
- [generic_param_attrs](generic-param-attrs.md)
|
||||
- [field_init_shorthand](field-init-shorthand.md)
|
||||
- [windows_subsystem](windows-subsystem.md)
|
||||
- [link_cfg](link-cfg.md)
|
||||
- [use_extern_macros](use-extern-macros.md)
|
||||
- [loop_break_value](loop-break-value.md)
|
||||
- [target_feature](target-feature.md)
|
||||
- [abi_ptx](abi-ptx.md)
|
||||
- [i128_type](i128-type.md)
|
||||
- [abi_unadjusted](abi-unadjusted.md)
|
||||
- [proc_macro](proc-macro.md)
|
||||
- [struct_field_attributes](struct-field-attributes.md)
|
||||
- [static_nobundle](static-nobundle.md)
|
||||
- [abi_msp430_interrupt](abi-msp430-interrupt.md)
|
||||
- [sanitizer_runtime](sanitizer-runtime.md)
|
7
src/doc/unstable-book/src/abi-msp430-interrupt.md
Normal file
7
src/doc/unstable-book/src/abi-msp430-interrupt.md
Normal file
@ -0,0 +1,7 @@
|
||||
# `abi_msp430_interrupt`
|
||||
|
||||
The tracking issue for this feature is: [#38487]
|
||||
|
||||
[#38487]: https://github.com/rust-lang/rust/issues/38487
|
||||
|
||||
------------------------
|
5
src/doc/unstable-book/src/abi-ptx.md
Normal file
5
src/doc/unstable-book/src/abi-ptx.md
Normal file
@ -0,0 +1,5 @@
|
||||
# `abi_ptx`
|
||||
|
||||
The tracking issue for this feature is: None.
|
||||
|
||||
------------------------
|
7
src/doc/unstable-book/src/abi-sysv64.md
Normal file
7
src/doc/unstable-book/src/abi-sysv64.md
Normal file
@ -0,0 +1,7 @@
|
||||
# `abi_sysv64`
|
||||
|
||||
The tracking issue for this feature is: [#36167]
|
||||
|
||||
[#36167]: https://github.com/rust-lang/rust/issues/36167
|
||||
|
||||
------------------------
|
6
src/doc/unstable-book/src/abi-unadjusted.md
Normal file
6
src/doc/unstable-book/src/abi-unadjusted.md
Normal file
@ -0,0 +1,6 @@
|
||||
# `abi_unadjusted`
|
||||
|
||||
The tracking issue for this feature is: none.
|
||||
|
||||
------------------------
|
||||
|
7
src/doc/unstable-book/src/abi-vectorcall.md
Normal file
7
src/doc/unstable-book/src/abi-vectorcall.md
Normal file
@ -0,0 +1,7 @@
|
||||
# `abi_vectorcall`
|
||||
|
||||
The tracking issue for this feature is: none.
|
||||
|
||||
------------------------
|
||||
|
||||
|
@ -1,20 +1,13 @@
|
||||
# Slice patterns
|
||||
# `advanced_slice_patterns`
|
||||
|
||||
If you want to match against a slice or array, you can use `&` with the
|
||||
`slice_patterns` feature:
|
||||
The tracking issue for this feature is: [#23121]
|
||||
|
||||
```rust
|
||||
#![feature(slice_patterns)]
|
||||
[#23121]: https://github.com/rust-lang/rust/issues/23121
|
||||
|
||||
fn main() {
|
||||
let v = vec!["match_this", "1"];
|
||||
See also [`slice_patterns`](slice-patterns.html).
|
||||
|
||||
------------------------
|
||||
|
||||
match &v[..] {
|
||||
&["match_this", second] => println!("The second element is {}", second),
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The `advanced_slice_patterns` gate lets you use `..` to indicate any number of
|
||||
elements inside a pattern matching a slice. This wildcard can only be used once
|
62
src/doc/unstable-book/src/alloc-jemalloc.md
Normal file
62
src/doc/unstable-book/src/alloc-jemalloc.md
Normal file
@ -0,0 +1,62 @@
|
||||
# `alloc_jemalloc`
|
||||
|
||||
The tracking issue for this feature is: [#33082]
|
||||
|
||||
[#33082]: https://github.com/rust-lang/rust/issues/33082
|
||||
|
||||
See also [`alloc_system`](alloc-system.html).
|
||||
|
||||
------------------------
|
||||
|
||||
The compiler currently ships two default allocators: `alloc_system` and
|
||||
`alloc_jemalloc` (some targets don't have jemalloc, however). These allocators
|
||||
are normal Rust crates and contain an implementation of the routines to
|
||||
allocate and deallocate memory. The standard library is not compiled assuming
|
||||
either one, and the compiler will decide which allocator is in use at
|
||||
compile-time depending on the type of output artifact being produced.
|
||||
|
||||
Binaries generated by the compiler will use `alloc_jemalloc` by default (where
|
||||
available). In this situation the compiler "controls the world" in the sense of
|
||||
it has power over the final link. Primarily this means that the allocator
|
||||
decision can be left up the compiler.
|
||||
|
||||
Dynamic and static libraries, however, will use `alloc_system` by default. Here
|
||||
Rust is typically a 'guest' in another application or another world where it
|
||||
cannot authoritatively decide what allocator is in use. As a result it resorts
|
||||
back to the standard APIs (e.g. `malloc` and `free`) for acquiring and releasing
|
||||
memory.
|
||||
|
||||
# Switching Allocators
|
||||
|
||||
Although the compiler's default choices may work most of the time, it's often
|
||||
necessary to tweak certain aspects. Overriding the compiler's decision about
|
||||
which allocator is in use is done simply by linking to the desired allocator:
|
||||
|
||||
```rust,no_run
|
||||
#![feature(alloc_system)]
|
||||
|
||||
extern crate alloc_system;
|
||||
|
||||
fn main() {
|
||||
let a = Box::new(4); // Allocates from the system allocator.
|
||||
println!("{}", a);
|
||||
}
|
||||
```
|
||||
|
||||
In this example the binary generated will not link to jemalloc by default but
|
||||
instead use the system allocator. Conversely to generate a dynamic library which
|
||||
uses jemalloc by default one would write:
|
||||
|
||||
```rust,ignore
|
||||
#![feature(alloc_jemalloc)]
|
||||
#![crate_type = "dylib"]
|
||||
|
||||
extern crate alloc_jemalloc;
|
||||
|
||||
pub fn foo() {
|
||||
let a = Box::new(4); // Allocates from jemalloc.
|
||||
println!("{}", a);
|
||||
}
|
||||
# fn main() {}
|
||||
```
|
||||
|
62
src/doc/unstable-book/src/alloc-system.md
Normal file
62
src/doc/unstable-book/src/alloc-system.md
Normal file
@ -0,0 +1,62 @@
|
||||
# `alloc_system`
|
||||
|
||||
The tracking issue for this feature is: [#33082]
|
||||
|
||||
[#33082]: https://github.com/rust-lang/rust/issues/33082
|
||||
|
||||
See also [`alloc_jemalloc`](alloc-jemalloc.html).
|
||||
|
||||
------------------------
|
||||
|
||||
The compiler currently ships two default allocators: `alloc_system` and
|
||||
`alloc_jemalloc` (some targets don't have jemalloc, however). These allocators
|
||||
are normal Rust crates and contain an implementation of the routines to
|
||||
allocate and deallocate memory. The standard library is not compiled assuming
|
||||
either one, and the compiler will decide which allocator is in use at
|
||||
compile-time depending on the type of output artifact being produced.
|
||||
|
||||
Binaries generated by the compiler will use `alloc_jemalloc` by default (where
|
||||
available). In this situation the compiler "controls the world" in the sense of
|
||||
it has power over the final link. Primarily this means that the allocator
|
||||
decision can be left up the compiler.
|
||||
|
||||
Dynamic and static libraries, however, will use `alloc_system` by default. Here
|
||||
Rust is typically a 'guest' in another application or another world where it
|
||||
cannot authoritatively decide what allocator is in use. As a result it resorts
|
||||
back to the standard APIs (e.g. `malloc` and `free`) for acquiring and releasing
|
||||
memory.
|
||||
|
||||
# Switching Allocators
|
||||
|
||||
Although the compiler's default choices may work most of the time, it's often
|
||||
necessary to tweak certain aspects. Overriding the compiler's decision about
|
||||
which allocator is in use is done simply by linking to the desired allocator:
|
||||
|
||||
```rust,no_run
|
||||
#![feature(alloc_system)]
|
||||
|
||||
extern crate alloc_system;
|
||||
|
||||
fn main() {
|
||||
let a = Box::new(4); // Allocates from the system allocator.
|
||||
println!("{}", a);
|
||||
}
|
||||
```
|
||||
|
||||
In this example the binary generated will not link to jemalloc by default but
|
||||
instead use the system allocator. Conversely to generate a dynamic library which
|
||||
uses jemalloc by default one would write:
|
||||
|
||||
```rust,ignore
|
||||
#![feature(alloc_jemalloc)]
|
||||
#![crate_type = "dylib"]
|
||||
|
||||
extern crate alloc_jemalloc;
|
||||
|
||||
pub fn foo() {
|
||||
let a = Box::new(4); // Allocates from jemalloc.
|
||||
println!("{}", a);
|
||||
}
|
||||
# fn main() {}
|
||||
```
|
||||
|
@ -1,69 +1,10 @@
|
||||
# Custom Allocators
|
||||
# `allocator`
|
||||
|
||||
Allocating memory isn't always the easiest thing to do, and while Rust generally
|
||||
takes care of this by default it often becomes necessary to customize how
|
||||
allocation occurs. The compiler and standard library currently allow switching
|
||||
out the default global allocator in use at compile time. The design is currently
|
||||
spelled out in [RFC 1183][rfc] but this will walk you through how to get your
|
||||
own allocator up and running.
|
||||
The tracking issue for this feature is: [#27389]
|
||||
|
||||
[rfc]: https://github.com/rust-lang/rfcs/blob/master/text/1183-swap-out-jemalloc.md
|
||||
[#27389]: https://github.com/rust-lang/rust/issues/27389
|
||||
|
||||
# Default Allocator
|
||||
|
||||
The compiler currently ships two default allocators: `alloc_system` and
|
||||
`alloc_jemalloc` (some targets don't have jemalloc, however). These allocators
|
||||
are normal Rust crates and contain an implementation of the routines to
|
||||
allocate and deallocate memory. The standard library is not compiled assuming
|
||||
either one, and the compiler will decide which allocator is in use at
|
||||
compile-time depending on the type of output artifact being produced.
|
||||
|
||||
Binaries generated by the compiler will use `alloc_jemalloc` by default (where
|
||||
available). In this situation the compiler "controls the world" in the sense of
|
||||
it has power over the final link. Primarily this means that the allocator
|
||||
decision can be left up the compiler.
|
||||
|
||||
Dynamic and static libraries, however, will use `alloc_system` by default. Here
|
||||
Rust is typically a 'guest' in another application or another world where it
|
||||
cannot authoritatively decide what allocator is in use. As a result it resorts
|
||||
back to the standard APIs (e.g. `malloc` and `free`) for acquiring and releasing
|
||||
memory.
|
||||
|
||||
# Switching Allocators
|
||||
|
||||
Although the compiler's default choices may work most of the time, it's often
|
||||
necessary to tweak certain aspects. Overriding the compiler's decision about
|
||||
which allocator is in use is done simply by linking to the desired allocator:
|
||||
|
||||
```rust,no_run
|
||||
#![feature(alloc_system)]
|
||||
|
||||
extern crate alloc_system;
|
||||
|
||||
fn main() {
|
||||
let a = Box::new(4); // Allocates from the system allocator.
|
||||
println!("{}", a);
|
||||
}
|
||||
```
|
||||
|
||||
In this example the binary generated will not link to jemalloc by default but
|
||||
instead use the system allocator. Conversely to generate a dynamic library which
|
||||
uses jemalloc by default one would write:
|
||||
|
||||
```rust,ignore
|
||||
#![feature(alloc_jemalloc)]
|
||||
#![crate_type = "dylib"]
|
||||
|
||||
extern crate alloc_jemalloc;
|
||||
|
||||
pub fn foo() {
|
||||
let a = Box::new(4); // Allocates from jemalloc.
|
||||
println!("{}", a);
|
||||
}
|
||||
# fn main() {}
|
||||
```
|
||||
|
||||
# Writing a custom allocator
|
||||
------------------------
|
||||
|
||||
Sometimes even the choices of jemalloc vs the system allocator aren't enough and
|
||||
an entirely new custom allocator is required. In this you'll write your own
|
||||
@ -154,7 +95,7 @@ fn main() {
|
||||
}
|
||||
```
|
||||
|
||||
# Custom allocator limitations
|
||||
## Custom allocator limitations
|
||||
|
||||
There are a few restrictions when working with custom allocators which may cause
|
||||
compiler errors:
|
||||
@ -169,3 +110,5 @@ compiler errors:
|
||||
depend on a crate which needs an allocator (e.g. circular dependencies are not
|
||||
allowed). This basically means that allocators must restrict themselves to
|
||||
libcore currently.
|
||||
|
||||
|
6
src/doc/unstable-book/src/allow-internal-unstable.md
Normal file
6
src/doc/unstable-book/src/allow-internal-unstable.md
Normal file
@ -0,0 +1,6 @@
|
||||
# `allow_internal_unstable`
|
||||
|
||||
The tracking issue for this feature is: None.
|
||||
|
||||
------------------------
|
||||
|
@ -1,4 +1,10 @@
|
||||
# Inline Assembly
|
||||
# `asm`
|
||||
|
||||
The tracking issue for this feature is: [#29722]
|
||||
|
||||
[#29722]: https://github.com/rust-lang/rust/issues/29722
|
||||
|
||||
------------------------
|
||||
|
||||
For extremely low-level manipulations and performance reasons, one
|
||||
might wish to control the CPU directly. Rust supports using inline
|
||||
@ -182,3 +188,4 @@ documentation as well][llvm-docs] for more information about clobbers,
|
||||
constraints, etc.
|
||||
|
||||
[llvm-docs]: http://llvm.org/docs/LangRef.html#inline-assembler-expressions
|
||||
|
@ -1,4 +1,10 @@
|
||||
# Associated Constants
|
||||
# `associated_consts`
|
||||
|
||||
The tracking issue for this feature is: [#29646]
|
||||
|
||||
[#29646]: https://github.com/rust-lang/rust/issues/29646
|
||||
|
||||
------------------------
|
||||
|
||||
With the `associated_consts` feature, you can define constants like this:
|
||||
|
10
src/doc/unstable-book/src/associated-type-defaults.md
Normal file
10
src/doc/unstable-book/src/associated-type-defaults.md
Normal file
@ -0,0 +1,10 @@
|
||||
# `associated_type_defaults`
|
||||
|
||||
The tracking issue for this feature is: [#29661]
|
||||
|
||||
[#29661]: https://github.com/rust-lang/rust/issues/29661
|
||||
|
||||
------------------------
|
||||
|
||||
|
||||
|
10
src/doc/unstable-book/src/attr-literals.md
Normal file
10
src/doc/unstable-book/src/attr-literals.md
Normal file
@ -0,0 +1,10 @@
|
||||
# `attr_literals`
|
||||
|
||||
The tracking issue for this feature is: [#34981]
|
||||
|
||||
[#34981]: https://github.com/rust-lang/rust/issues/34981
|
||||
|
||||
------------------------
|
||||
|
||||
|
||||
|
32
src/doc/unstable-book/src/box-patterns.md
Normal file
32
src/doc/unstable-book/src/box-patterns.md
Normal file
@ -0,0 +1,32 @@
|
||||
# `box_patterns`
|
||||
|
||||
The tracking issue for this feature is: [#29641]
|
||||
|
||||
[#29641]: https://github.com/rust-lang/rust/issues/29641
|
||||
|
||||
See also [`box_syntax`](box-syntax.html)
|
||||
|
||||
------------------------
|
||||
|
||||
Box patterns let you match on `Box<T>`s:
|
||||
|
||||
|
||||
```rust
|
||||
#![feature(box_patterns)]
|
||||
|
||||
fn main() {
|
||||
let b = Some(Box::new(5));
|
||||
match b {
|
||||
Some(box n) if n < 0 => {
|
||||
println!("Box contains negative number {}", n);
|
||||
},
|
||||
Some(box n) if n >= 0 => {
|
||||
println!("Box contains non-negative number {}", n);
|
||||
},
|
||||
None => {
|
||||
println!("No box");
|
||||
},
|
||||
_ => unreachable!()
|
||||
}
|
||||
}
|
||||
```
|
22
src/doc/unstable-book/src/box-syntax.md
Normal file
22
src/doc/unstable-book/src/box-syntax.md
Normal file
@ -0,0 +1,22 @@
|
||||
# `box_syntax`
|
||||
|
||||
The tracking issue for this feature is: [#27779]
|
||||
|
||||
[#27779]: https://github.com/rust-lang/rust/issues/27779
|
||||
|
||||
See also [`box_patterns`](box-patterns.html)
|
||||
|
||||
------------------------
|
||||
|
||||
Currently the only stable way to create a `Box` is via the `Box::new` method.
|
||||
Also it is not possible in stable Rust to destructure a `Box` in a match
|
||||
pattern. The unstable `box` keyword can be used to create a `Box`. An example
|
||||
usage would be:
|
||||
|
||||
```rust
|
||||
#![feature(box_syntax)]
|
||||
|
||||
fn main() {
|
||||
let b = box 5;
|
||||
}
|
||||
```
|
10
src/doc/unstable-book/src/cfg-target-feature.md
Normal file
10
src/doc/unstable-book/src/cfg-target-feature.md
Normal file
@ -0,0 +1,10 @@
|
||||
# `cfg_target_feature`
|
||||
|
||||
The tracking issue for this feature is: [#29717]
|
||||
|
||||
[#29717]: https://github.com/rust-lang/rust/issues/29717
|
||||
|
||||
------------------------
|
||||
|
||||
|
||||
|
10
src/doc/unstable-book/src/cfg-target-has-atomic.md
Normal file
10
src/doc/unstable-book/src/cfg-target-has-atomic.md
Normal file
@ -0,0 +1,10 @@
|
||||
# `cfg_target_has_atomic`
|
||||
|
||||
The tracking issue for this feature is: [#32976]
|
||||
|
||||
[#32976]: https://github.com/rust-lang/rust/issues/32976
|
||||
|
||||
------------------------
|
||||
|
||||
|
||||
|
10
src/doc/unstable-book/src/cfg-target-thread-local.md
Normal file
10
src/doc/unstable-book/src/cfg-target-thread-local.md
Normal file
@ -0,0 +1,10 @@
|
||||
# `cfg_target_thread_local`
|
||||
|
||||
The tracking issue for this feature is: [#29594]
|
||||
|
||||
[#29594]: https://github.com/rust-lang/rust/issues/29594
|
||||
|
||||
------------------------
|
||||
|
||||
|
||||
|
10
src/doc/unstable-book/src/cfg-target-vendor.md
Normal file
10
src/doc/unstable-book/src/cfg-target-vendor.md
Normal file
@ -0,0 +1,10 @@
|
||||
# `cfg_target_feature`
|
||||
|
||||
The tracking issue for this feature is: [#29717]
|
||||
|
||||
[#29717]: https://github.com/rust-lang/rust/issues/29717
|
||||
|
||||
------------------------
|
||||
|
||||
|
||||
|
6
src/doc/unstable-book/src/compiler-builtins.md
Normal file
6
src/doc/unstable-book/src/compiler-builtins.md
Normal file
@ -0,0 +1,6 @@
|
||||
# `compiler_builtins`
|
||||
|
||||
The tracking issue for this feature is: None.
|
||||
|
||||
------------------------
|
||||
|
10
src/doc/unstable-book/src/concat-idents.md
Normal file
10
src/doc/unstable-book/src/concat-idents.md
Normal file
@ -0,0 +1,10 @@
|
||||
# `concat_idents`
|
||||
|
||||
The tracking issue for this feature is: [#29599]
|
||||
|
||||
[#29599]: https://github.com/rust-lang/rust/issues/29599
|
||||
|
||||
------------------------
|
||||
|
||||
|
||||
|
10
src/doc/unstable-book/src/conservative-impl-trait.md
Normal file
10
src/doc/unstable-book/src/conservative-impl-trait.md
Normal file
@ -0,0 +1,10 @@
|
||||
# `conservative_impl_trait`
|
||||
|
||||
The tracking issue for this feature is: [#34511]
|
||||
|
||||
[#34511]: https://github.com/rust-lang/rust/issues/34511
|
||||
|
||||
------------------------
|
||||
|
||||
|
||||
|
10
src/doc/unstable-book/src/const-fn.md
Normal file
10
src/doc/unstable-book/src/const-fn.md
Normal file
@ -0,0 +1,10 @@
|
||||
# `const_fn`
|
||||
|
||||
The tracking issue for this feature is: [#24111]
|
||||
|
||||
[#24111]: https://github.com/rust-lang/rust/issues/24111
|
||||
|
||||
------------------------
|
||||
|
||||
|
||||
|
10
src/doc/unstable-book/src/const-indexing.md
Normal file
10
src/doc/unstable-book/src/const-indexing.md
Normal file
@ -0,0 +1,10 @@
|
||||
# `const_indexing`
|
||||
|
||||
The tracking issue for this feature is: [#29947]
|
||||
|
||||
[#29947]: https://github.com/rust-lang/rust/issues/29947
|
||||
|
||||
------------------------
|
||||
|
||||
|
||||
|
10
src/doc/unstable-book/src/custom-attribute.md
Normal file
10
src/doc/unstable-book/src/custom-attribute.md
Normal file
@ -0,0 +1,10 @@
|
||||
# `custom_attribute`
|
||||
|
||||
The tracking issue for this feature is: [#29642]
|
||||
|
||||
[#29642]: https://github.com/rust-lang/rust/issues/29642
|
||||
|
||||
------------------------
|
||||
|
||||
|
||||
|
10
src/doc/unstable-book/src/custom-derive.md
Normal file
10
src/doc/unstable-book/src/custom-derive.md
Normal file
@ -0,0 +1,10 @@
|
||||
# `custom_derive`
|
||||
|
||||
The tracking issue for this feature is: [#29644]
|
||||
|
||||
[#29644]: https://github.com/rust-lang/rust/issues/29644
|
||||
|
||||
------------------------
|
||||
|
||||
|
||||
|
10
src/doc/unstable-book/src/default-type-parameter-fallback.md
Normal file
10
src/doc/unstable-book/src/default-type-parameter-fallback.md
Normal file
@ -0,0 +1,10 @@
|
||||
# `default_type_parameter_fallback`
|
||||
|
||||
The tracking issue for this feature is: [#27336]
|
||||
|
||||
[#27336]: https://github.com/rust-lang/rust/issues/27336
|
||||
|
||||
------------------------
|
||||
|
||||
|
||||
|
10
src/doc/unstable-book/src/drop-types-in-const.md
Normal file
10
src/doc/unstable-book/src/drop-types-in-const.md
Normal file
@ -0,0 +1,10 @@
|
||||
# `drop_types_in_const`
|
||||
|
||||
The tracking issue for this feature is: [#33156]
|
||||
|
||||
[#33156]: https://github.com/rust-lang/rust/issues/33156
|
||||
|
||||
------------------------
|
||||
|
||||
|
||||
|
10
src/doc/unstable-book/src/dropck-eyepatch.md
Normal file
10
src/doc/unstable-book/src/dropck-eyepatch.md
Normal file
@ -0,0 +1,10 @@
|
||||
# `dropck_eyepatch`
|
||||
|
||||
The tracking issue for this feature is: [#34761]
|
||||
|
||||
[#34761]: https://github.com/rust-lang/rust/issues/34761
|
||||
|
||||
------------------------
|
||||
|
||||
|
||||
|
10
src/doc/unstable-book/src/dropck-parametricity.md
Normal file
10
src/doc/unstable-book/src/dropck-parametricity.md
Normal file
@ -0,0 +1,10 @@
|
||||
# `dropck_parametricity`
|
||||
|
||||
The tracking issue for this feature is: [#28498]
|
||||
|
||||
[#28498]: https://github.com/rust-lang/rust/issues/28498
|
||||
|
||||
------------------------
|
||||
|
||||
|
||||
|
10
src/doc/unstable-book/src/exclusive-range-pattern.md
Normal file
10
src/doc/unstable-book/src/exclusive-range-pattern.md
Normal file
@ -0,0 +1,10 @@
|
||||
# `exclusive_range_pattern`
|
||||
|
||||
The tracking issue for this feature is: [#37854]
|
||||
|
||||
[#37854]: https://github.com/rust-lang/rust/issues/37854
|
||||
|
||||
------------------------
|
||||
|
||||
|
||||
|
10
src/doc/unstable-book/src/field-init-shorthand.md
Normal file
10
src/doc/unstable-book/src/field-init-shorthand.md
Normal file
@ -0,0 +1,10 @@
|
||||
# `field_init_shorthand`
|
||||
|
||||
The tracking issue for this feature is: [#37340]
|
||||
|
||||
[#37340]: https://github.com/rust-lang/rust/issues/37340
|
||||
|
||||
------------------------
|
||||
|
||||
|
||||
|
10
src/doc/unstable-book/src/fundamental.md
Normal file
10
src/doc/unstable-book/src/fundamental.md
Normal file
@ -0,0 +1,10 @@
|
||||
# `fundamental`
|
||||
|
||||
The tracking issue for this feature is: [#29635]
|
||||
|
||||
[#29635]: https://github.com/rust-lang/rust/issues/29635
|
||||
|
||||
------------------------
|
||||
|
||||
|
||||
|
10
src/doc/unstable-book/src/generic-param-attrs.md
Normal file
10
src/doc/unstable-book/src/generic-param-attrs.md
Normal file
@ -0,0 +1,10 @@
|
||||
# `generic_param_attrs`
|
||||
|
||||
The tracking issue for this feature is: [#34761]
|
||||
|
||||
[#34761]: https://github.com/rust-lang/rust/issues/34761
|
||||
|
||||
------------------------
|
||||
|
||||
|
||||
|
10
src/doc/unstable-book/src/i128-type.md
Normal file
10
src/doc/unstable-book/src/i128-type.md
Normal file
@ -0,0 +1,10 @@
|
||||
# `i128_type`
|
||||
|
||||
The tracking issue for this feature is: [#35118]
|
||||
|
||||
[#35118]: https://github.com/rust-lang/rust/issues/35118
|
||||
|
||||
------------------------
|
||||
|
||||
|
||||
|
10
src/doc/unstable-book/src/inclusive-range-syntax.md
Normal file
10
src/doc/unstable-book/src/inclusive-range-syntax.md
Normal file
@ -0,0 +1,10 @@
|
||||
# `inclusive_range_syntax`
|
||||
|
||||
The tracking issue for this feature is: [#28237]
|
||||
|
||||
[#28237]: https://github.com/rust-lang/rust/issues/28237
|
||||
|
||||
------------------------
|
||||
|
||||
|
||||
|
@ -1,8 +1,13 @@
|
||||
# Intrinsics
|
||||
# `intrinsics`
|
||||
|
||||
The tracking issue for this feature is: None.
|
||||
|
||||
Intrinsics are never intended to be stable directly, but intrinsics are often
|
||||
exported in some sort of stable manner. Prefer using the stable interfaces to
|
||||
the intrinsic directly when you can.
|
||||
|
||||
------------------------
|
||||
|
||||
> **Note**: intrinsics will forever have an unstable interface, it is
|
||||
> recommended to use the stable interfaces of libcore rather than intrinsics
|
||||
> directly.
|
||||
|
||||
These are imported as if they were FFI functions, with the special
|
||||
`rust-intrinsic` ABI. For example, if one was in a freestanding
|
@ -1,23 +1,97 @@
|
||||
# No stdlib
|
||||
# `lang_items`
|
||||
|
||||
Rust’s standard library provides a lot of useful functionality, but assumes
|
||||
support for various features of its host system: threads, networking, heap
|
||||
allocation, and others. There are systems that do not have these features,
|
||||
however, and Rust can work with those too! To do so, we tell Rust that we
|
||||
don’t want to use the standard library via an attribute: `#![no_std]`.
|
||||
The tracking issue for this feature is: None.
|
||||
|
||||
> Note: This feature is technically stable, but there are some caveats. For
|
||||
> one, you can build a `#![no_std]` _library_ on stable, but not a _binary_.
|
||||
> For details on libraries without the standard library, see [the chapter on
|
||||
> `#![no_std]`](using-rust-without-the-standard-library.html)
|
||||
------------------------
|
||||
|
||||
Obviously there's more to life than just libraries: one can use
|
||||
`#[no_std]` with an executable.
|
||||
The `rustc` compiler has certain pluggable operations, that is,
|
||||
functionality that isn't hard-coded into the language, but is
|
||||
implemented in libraries, with a special marker to tell the compiler
|
||||
it exists. The marker is the attribute `#[lang = "..."]` and there are
|
||||
various different values of `...`, i.e. various different 'lang
|
||||
items'.
|
||||
|
||||
For example, `Box` pointers require two lang items, one for allocation
|
||||
and one for deallocation. A freestanding program that uses the `Box`
|
||||
sugar for dynamic allocations via `malloc` and `free`:
|
||||
|
||||
```rust,ignore
|
||||
#![feature(lang_items, box_syntax, start, libc, core_intrinsics)]
|
||||
#![no_std]
|
||||
use core::intrinsics;
|
||||
|
||||
extern crate libc;
|
||||
|
||||
#[lang = "owned_box"]
|
||||
pub struct Box<T>(*mut T);
|
||||
|
||||
#[lang = "exchange_malloc"]
|
||||
unsafe fn allocate(size: usize, _align: usize) -> *mut u8 {
|
||||
let p = libc::malloc(size as libc::size_t) as *mut u8;
|
||||
|
||||
// Check if `malloc` failed:
|
||||
if p as usize == 0 {
|
||||
intrinsics::abort();
|
||||
}
|
||||
|
||||
p
|
||||
}
|
||||
|
||||
#[lang = "exchange_free"]
|
||||
unsafe fn deallocate(ptr: *mut u8, _size: usize, _align: usize) {
|
||||
libc::free(ptr as *mut libc::c_void)
|
||||
}
|
||||
|
||||
#[lang = "box_free"]
|
||||
unsafe fn box_free<T: ?Sized>(ptr: *mut T) {
|
||||
deallocate(ptr as *mut u8, ::core::mem::size_of_val(&*ptr), ::core::mem::align_of_val(&*ptr));
|
||||
}
|
||||
|
||||
#[start]
|
||||
fn main(argc: isize, argv: *const *const u8) -> isize {
|
||||
let x = box 1;
|
||||
|
||||
0
|
||||
}
|
||||
|
||||
#[lang = "eh_personality"] extern fn rust_eh_personality() {}
|
||||
#[lang = "panic_fmt"] extern fn rust_begin_panic() -> ! { unsafe { intrinsics::abort() } }
|
||||
# #[lang = "eh_unwind_resume"] extern fn rust_eh_unwind_resume() {}
|
||||
# #[no_mangle] pub extern fn rust_eh_register_frames () {}
|
||||
# #[no_mangle] pub extern fn rust_eh_unregister_frames () {}
|
||||
```
|
||||
|
||||
Note the use of `abort`: the `exchange_malloc` lang item is assumed to
|
||||
return a valid pointer, and so needs to do the check internally.
|
||||
|
||||
Other features provided by lang items include:
|
||||
|
||||
- overloadable operators via traits: the traits corresponding to the
|
||||
`==`, `<`, dereferencing (`*`) and `+` (etc.) operators are all
|
||||
marked with lang items; those specific four are `eq`, `ord`,
|
||||
`deref`, and `add` respectively.
|
||||
- stack unwinding and general failure; the `eh_personality`,
|
||||
`eh_unwind_resume`, `fail` and `fail_bounds_checks` lang items.
|
||||
- the traits in `std::marker` used to indicate types of
|
||||
various kinds; lang items `send`, `sync` and `copy`.
|
||||
- the marker types and variance indicators found in
|
||||
`std::marker`; lang items `covariant_type`,
|
||||
`contravariant_lifetime`, etc.
|
||||
|
||||
Lang items are loaded lazily by the compiler; e.g. if one never uses
|
||||
`Box` then there is no need to define functions for `exchange_malloc`
|
||||
and `exchange_free`. `rustc` will emit an error when an item is needed
|
||||
but not found in the current crate or any that it depends on.
|
||||
|
||||
Most lang items are defined by `libcore`, but if you're trying to build
|
||||
an executable without the standard library, you'll run into the need
|
||||
for lang items. The rest of this page focuses on this use-case, even though
|
||||
lang items are a bit broader than that.
|
||||
|
||||
### Using libc
|
||||
|
||||
In order to build a `#[no_std]` executable we will need libc as a dependency. We can specify
|
||||
this using our `Cargo.toml` file:
|
||||
In order to build a `#[no_std]` executable we will need libc as a dependency.
|
||||
We can specify this using our `Cargo.toml` file:
|
||||
|
||||
```toml
|
||||
[dependencies]
|
32
src/doc/unstable-book/src/link-args.md
Normal file
32
src/doc/unstable-book/src/link-args.md
Normal file
@ -0,0 +1,32 @@
|
||||
# `link_args`
|
||||
|
||||
The tracking issue for this feature is: [#29596]
|
||||
|
||||
[#29596]: https://github.com/rust-lang/rust/issues/29596
|
||||
|
||||
------------------------
|
||||
|
||||
You can tell `rustc` how to customize linking, and that is via the `link_args`
|
||||
attribute. This attribute is applied to `extern` blocks and specifies raw flags
|
||||
which need to get passed to the linker when producing an artifact. An example
|
||||
usage would be:
|
||||
|
||||
```rust,no_run
|
||||
#![feature(link_args)]
|
||||
|
||||
#[link_args = "-foo -bar -baz"]
|
||||
extern {}
|
||||
# fn main() {}
|
||||
```
|
||||
|
||||
Note that this feature is currently hidden behind the `feature(link_args)` gate
|
||||
because this is not a sanctioned way of performing linking. Right now `rustc`
|
||||
shells out to the system linker (`gcc` on most systems, `link.exe` on MSVC), so
|
||||
it makes sense to provide extra command line arguments, but this will not
|
||||
always be the case. In the future `rustc` may use LLVM directly to link native
|
||||
libraries, in which case `link_args` will have no meaning. You can achieve the
|
||||
same effect as the `link_args` attribute with the `-C link-args` argument to
|
||||
`rustc`.
|
||||
|
||||
It is highly recommended to *not* use this attribute, and rather use the more
|
||||
formal `#[link(...)]` attribute on `extern` blocks instead.
|
10
src/doc/unstable-book/src/link-cfg.md
Normal file
10
src/doc/unstable-book/src/link-cfg.md
Normal file
@ -0,0 +1,10 @@
|
||||
# `link_cfg`
|
||||
|
||||
The tracking issue for this feature is: [#37406]
|
||||
|
||||
[#37406]: https://github.com/rust-lang/rust/issues/37406
|
||||
|
||||
------------------------
|
||||
|
||||
|
||||
|
10
src/doc/unstable-book/src/link-llvm-intrinsics.md
Normal file
10
src/doc/unstable-book/src/link-llvm-intrinsics.md
Normal file
@ -0,0 +1,10 @@
|
||||
# `link_llvm_intrinsics`
|
||||
|
||||
The tracking issue for this feature is: [#29602]
|
||||
|
||||
[#29602]: https://github.com/rust-lang/rust/issues/29602
|
||||
|
||||
------------------------
|
||||
|
||||
|
||||
|
10
src/doc/unstable-book/src/linkage.md
Normal file
10
src/doc/unstable-book/src/linkage.md
Normal file
@ -0,0 +1,10 @@
|
||||
# `linkage`
|
||||
|
||||
The tracking issue for this feature is: [#29603]
|
||||
|
||||
[#29603]: https://github.com/rust-lang/rust/issues/29603
|
||||
|
||||
------------------------
|
||||
|
||||
|
||||
|
10
src/doc/unstable-book/src/log-syntax.md
Normal file
10
src/doc/unstable-book/src/log-syntax.md
Normal file
@ -0,0 +1,10 @@
|
||||
# `log_syntax`
|
||||
|
||||
The tracking issue for this feature is: [#29598]
|
||||
|
||||
[#29598]: https://github.com/rust-lang/rust/issues/29598
|
||||
|
||||
------------------------
|
||||
|
||||
|
||||
|
10
src/doc/unstable-book/src/loop-break-value.md
Normal file
10
src/doc/unstable-book/src/loop-break-value.md
Normal file
@ -0,0 +1,10 @@
|
||||
# `loop_break_value`
|
||||
|
||||
The tracking issue for this feature is: [#37339]
|
||||
|
||||
[#37339]: https://github.com/rust-lang/rust/issues/37339
|
||||
|
||||
------------------------
|
||||
|
||||
|
||||
|
10
src/doc/unstable-book/src/macro-reexport.md
Normal file
10
src/doc/unstable-book/src/macro-reexport.md
Normal file
@ -0,0 +1,10 @@
|
||||
# `macro_reexport`
|
||||
|
||||
The tracking issue for this feature is: [#29638]
|
||||
|
||||
[#29638]: https://github.com/rust-lang/rust/issues/29638
|
||||
|
||||
------------------------
|
||||
|
||||
|
||||
|
10
src/doc/unstable-book/src/main.md
Normal file
10
src/doc/unstable-book/src/main.md
Normal file
@ -0,0 +1,10 @@
|
||||
# `main`
|
||||
|
||||
The tracking issue for this feature is: [#29634]
|
||||
|
||||
[#29634]: https://github.com/rust-lang/rust/issues/29634
|
||||
|
||||
------------------------
|
||||
|
||||
|
||||
|
10
src/doc/unstable-book/src/naked-functions.md
Normal file
10
src/doc/unstable-book/src/naked-functions.md
Normal file
@ -0,0 +1,10 @@
|
||||
# `naked_functions`
|
||||
|
||||
The tracking issue for this feature is: [#32408]
|
||||
|
||||
[#32408]: https://github.com/rust-lang/rust/issues/32408
|
||||
|
||||
------------------------
|
||||
|
||||
|
||||
|
10
src/doc/unstable-book/src/needs-allocator.md
Normal file
10
src/doc/unstable-book/src/needs-allocator.md
Normal file
@ -0,0 +1,10 @@
|
||||
# `needs_allocator`
|
||||
|
||||
The tracking issue for this feature is: [#27389]
|
||||
|
||||
[#27389]: https://github.com/rust-lang/rust/issues/27389
|
||||
|
||||
------------------------
|
||||
|
||||
|
||||
|
10
src/doc/unstable-book/src/needs-panic-runtime.md
Normal file
10
src/doc/unstable-book/src/needs-panic-runtime.md
Normal file
@ -0,0 +1,10 @@
|
||||
# `needs_panic_runtime`
|
||||
|
||||
The tracking issue for this feature is: [#32837]
|
||||
|
||||
[#32837]: https://github.com/rust-lang/rust/issues/32837
|
||||
|
||||
------------------------
|
||||
|
||||
|
||||
|
10
src/doc/unstable-book/src/never-type.md
Normal file
10
src/doc/unstable-book/src/never-type.md
Normal file
@ -0,0 +1,10 @@
|
||||
# `never_type`
|
||||
|
||||
The tracking issue for this feature is: [#35121]
|
||||
|
||||
[#35121]: https://github.com/rust-lang/rust/issues/35121
|
||||
|
||||
------------------------
|
||||
|
||||
|
||||
|
10
src/doc/unstable-book/src/no-core.md
Normal file
10
src/doc/unstable-book/src/no-core.md
Normal file
@ -0,0 +1,10 @@
|
||||
# `no_core`
|
||||
|
||||
The tracking issue for this feature is: [#29639]
|
||||
|
||||
[#29639]: https://github.com/rust-lang/rust/issues/29639
|
||||
|
||||
------------------------
|
||||
|
||||
|
||||
|
10
src/doc/unstable-book/src/no-debug.md
Normal file
10
src/doc/unstable-book/src/no-debug.md
Normal file
@ -0,0 +1,10 @@
|
||||
# `no_debug`
|
||||
|
||||
The tracking issue for this feature is: [#29721]
|
||||
|
||||
[#29721]: https://github.com/rust-lang/rust/issues/29721
|
||||
|
||||
------------------------
|
||||
|
||||
|
||||
|
10
src/doc/unstable-book/src/non-ascii-idents.md
Normal file
10
src/doc/unstable-book/src/non-ascii-idents.md
Normal file
@ -0,0 +1,10 @@
|
||||
# `non_ascii_idents`
|
||||
|
||||
The tracking issue for this feature is: [#28979]
|
||||
|
||||
[#28979]: https://github.com/rust-lang/rust/issues/28979
|
||||
|
||||
------------------------
|
||||
|
||||
|
||||
|
@ -0,0 +1,6 @@
|
||||
# `omit_gdb_pretty_printer_section`
|
||||
|
||||
The tracking issue for this feature is: None.
|
||||
|
||||
------------------------
|
||||
|
10
src/doc/unstable-book/src/on-unimplemented.md
Normal file
10
src/doc/unstable-book/src/on-unimplemented.md
Normal file
@ -0,0 +1,10 @@
|
||||
# `on_unimplemented`
|
||||
|
||||
The tracking issue for this feature is: [#29628]
|
||||
|
||||
[#29628]: https://github.com/rust-lang/rust/issues/29628
|
||||
|
||||
------------------------
|
||||
|
||||
|
||||
|
9
src/doc/unstable-book/src/optin-builtin-traits.md
Normal file
9
src/doc/unstable-book/src/optin-builtin-traits.md
Normal file
@ -0,0 +1,9 @@
|
||||
# `optin_builtin_traits`
|
||||
|
||||
The tracking issue for this feature is: [#13231]
|
||||
|
||||
[#13231]: https://github.com/rust-lang/rust/issues/13231
|
||||
|
||||
------------------------
|
||||
|
||||
|
10
src/doc/unstable-book/src/panic-runtime.md
Normal file
10
src/doc/unstable-book/src/panic-runtime.md
Normal file
@ -0,0 +1,10 @@
|
||||
# `panic_runtime`
|
||||
|
||||
The tracking issue for this feature is: [#32837]
|
||||
|
||||
[#32837]: https://github.com/rust-lang/rust/issues/32837
|
||||
|
||||
------------------------
|
||||
|
||||
|
||||
|
10
src/doc/unstable-book/src/placement-in-syntax.md
Normal file
10
src/doc/unstable-book/src/placement-in-syntax.md
Normal file
@ -0,0 +1,10 @@
|
||||
# `placement_in_syntax`
|
||||
|
||||
The tracking issue for this feature is: [#27779]
|
||||
|
||||
[#27779]: https://github.com/rust-lang/rust/issues/27779
|
||||
|
||||
------------------------
|
||||
|
||||
|
||||
|
10
src/doc/unstable-book/src/platform-intrinsics.md
Normal file
10
src/doc/unstable-book/src/platform-intrinsics.md
Normal file
@ -0,0 +1,10 @@
|
||||
# `platform_intrinsics`
|
||||
|
||||
The tracking issue for this feature is: [#27731]
|
||||
|
||||
[#27731]: https://github.com/rust-lang/rust/issues/27731
|
||||
|
||||
------------------------
|
||||
|
||||
|
||||
|
13
src/doc/unstable-book/src/plugin-registrar.md
Normal file
13
src/doc/unstable-book/src/plugin-registrar.md
Normal file
@ -0,0 +1,13 @@
|
||||
# `plugin_registrar`
|
||||
|
||||
The tracking issue for this feature is: [#29597]
|
||||
|
||||
[#29597]: https://github.com/rust-lang/rust/issues/29597
|
||||
|
||||
This feature is part of "compiler plugins." It will often be used with the
|
||||
[`plugin`] and `rustc_private` features as well. For more details, see
|
||||
their docs.
|
||||
|
||||
[`plugin`]: plugin.html
|
||||
|
||||
------------------------
|
263
src/doc/unstable-book/src/plugin.md
Normal file
263
src/doc/unstable-book/src/plugin.md
Normal file
@ -0,0 +1,263 @@
|
||||
# `plugin`
|
||||
|
||||
The tracking issue for this feature is: [#29597]
|
||||
|
||||
[#29597]: https://github.com/rust-lang/rust/issues/29597
|
||||
|
||||
|
||||
This feature is part of "compiler plugins." It will often be used with the
|
||||
[`plugin_registrar`] and `rustc_private` features.
|
||||
|
||||
[`plugin_registrar`]: plugin-registrar.html
|
||||
|
||||
------------------------
|
||||
|
||||
`rustc` can load compiler plugins, which are user-provided libraries that
|
||||
extend the compiler's behavior with new syntax extensions, lint checks, etc.
|
||||
|
||||
A plugin is a dynamic library crate with a designated *registrar* function that
|
||||
registers extensions with `rustc`. Other crates can load these extensions using
|
||||
the crate attribute `#![plugin(...)]`. See the
|
||||
`rustc_plugin` documentation for more about the
|
||||
mechanics of defining and loading a plugin.
|
||||
|
||||
If present, arguments passed as `#![plugin(foo(... args ...))]` are not
|
||||
interpreted by rustc itself. They are provided to the plugin through the
|
||||
`Registry`'s `args` method.
|
||||
|
||||
In the vast majority of cases, a plugin should *only* be used through
|
||||
`#![plugin]` and not through an `extern crate` item. Linking a plugin would
|
||||
pull in all of libsyntax and librustc as dependencies of your crate. This is
|
||||
generally unwanted unless you are building another plugin. The
|
||||
`plugin_as_library` lint checks these guidelines.
|
||||
|
||||
The usual practice is to put compiler plugins in their own crate, separate from
|
||||
any `macro_rules!` macros or ordinary Rust code meant to be used by consumers
|
||||
of a library.
|
||||
|
||||
# Syntax extensions
|
||||
|
||||
Plugins can extend Rust's syntax in various ways. One kind of syntax extension
|
||||
is the procedural macro. These are invoked the same way as [ordinary
|
||||
macros](../book/macros.html), but the expansion is performed by arbitrary Rust
|
||||
code that manipulates syntax trees at
|
||||
compile time.
|
||||
|
||||
Let's write a plugin
|
||||
[`roman_numerals.rs`](https://github.com/rust-lang/rust/blob/master/src/test/run-pass-fulldeps/auxiliary/roman_numerals.rs)
|
||||
that implements Roman numeral integer literals.
|
||||
|
||||
```rust,ignore
|
||||
#![crate_type="dylib"]
|
||||
#![feature(plugin_registrar, rustc_private)]
|
||||
|
||||
extern crate syntax;
|
||||
extern crate rustc;
|
||||
extern crate rustc_plugin;
|
||||
|
||||
use syntax::parse::token;
|
||||
use syntax::tokenstream::TokenTree;
|
||||
use syntax::ext::base::{ExtCtxt, MacResult, DummyResult, MacEager};
|
||||
use syntax::ext::build::AstBuilder; // A trait for expr_usize.
|
||||
use syntax::ext::quote::rt::Span;
|
||||
use rustc_plugin::Registry;
|
||||
|
||||
fn expand_rn(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree])
|
||||
-> Box<MacResult + 'static> {
|
||||
|
||||
static NUMERALS: &'static [(&'static str, usize)] = &[
|
||||
("M", 1000), ("CM", 900), ("D", 500), ("CD", 400),
|
||||
("C", 100), ("XC", 90), ("L", 50), ("XL", 40),
|
||||
("X", 10), ("IX", 9), ("V", 5), ("IV", 4),
|
||||
("I", 1)];
|
||||
|
||||
if args.len() != 1 {
|
||||
cx.span_err(
|
||||
sp,
|
||||
&format!("argument should be a single identifier, but got {} arguments", args.len()));
|
||||
return DummyResult::any(sp);
|
||||
}
|
||||
|
||||
let text = match args[0] {
|
||||
TokenTree::Token(_, token::Ident(s)) => s.to_string(),
|
||||
_ => {
|
||||
cx.span_err(sp, "argument should be a single identifier");
|
||||
return DummyResult::any(sp);
|
||||
}
|
||||
};
|
||||
|
||||
let mut text = &*text;
|
||||
let mut total = 0;
|
||||
while !text.is_empty() {
|
||||
match NUMERALS.iter().find(|&&(rn, _)| text.starts_with(rn)) {
|
||||
Some(&(rn, val)) => {
|
||||
total += val;
|
||||
text = &text[rn.len()..];
|
||||
}
|
||||
None => {
|
||||
cx.span_err(sp, "invalid Roman numeral");
|
||||
return DummyResult::any(sp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MacEager::expr(cx.expr_usize(sp, total))
|
||||
}
|
||||
|
||||
#[plugin_registrar]
|
||||
pub fn plugin_registrar(reg: &mut Registry) {
|
||||
reg.register_macro("rn", expand_rn);
|
||||
}
|
||||
```
|
||||
|
||||
Then we can use `rn!()` like any other macro:
|
||||
|
||||
```rust,ignore
|
||||
#![feature(plugin)]
|
||||
#![plugin(roman_numerals)]
|
||||
|
||||
fn main() {
|
||||
assert_eq!(rn!(MMXV), 2015);
|
||||
}
|
||||
```
|
||||
|
||||
The advantages over a simple `fn(&str) -> u32` are:
|
||||
|
||||
* The (arbitrarily complex) conversion is done at compile time.
|
||||
* Input validation is also performed at compile time.
|
||||
* It can be extended to allow use in patterns, which effectively gives
|
||||
a way to define new literal syntax for any data type.
|
||||
|
||||
In addition to procedural macros, you can define new
|
||||
[`derive`](../reference/attributes.html#derive)-like attributes and other kinds
|
||||
of extensions. See `Registry::register_syntax_extension` and the
|
||||
`SyntaxExtension` enum. For a more involved macro example, see
|
||||
[`regex_macros`](https://github.com/rust-lang/regex/blob/master/regex_macros/src/lib.rs).
|
||||
|
||||
|
||||
## Tips and tricks
|
||||
|
||||
Some of the [macro debugging tips](../book/macros.html#debugging-macro-code) are applicable.
|
||||
|
||||
You can use `syntax::parse` to turn token trees into
|
||||
higher-level syntax elements like expressions:
|
||||
|
||||
```rust,ignore
|
||||
fn expand_foo(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree])
|
||||
-> Box<MacResult+'static> {
|
||||
|
||||
let mut parser = cx.new_parser_from_tts(args);
|
||||
|
||||
let expr: P<Expr> = parser.parse_expr();
|
||||
```
|
||||
|
||||
Looking through [`libsyntax` parser
|
||||
code](https://github.com/rust-lang/rust/blob/master/src/libsyntax/parse/parser.rs)
|
||||
will give you a feel for how the parsing infrastructure works.
|
||||
|
||||
Keep the `Span`s of everything you parse, for better error reporting. You can
|
||||
wrap `Spanned` around your custom data structures.
|
||||
|
||||
Calling `ExtCtxt::span_fatal` will immediately abort compilation. It's better to
|
||||
instead call `ExtCtxt::span_err` and return `DummyResult` so that the compiler
|
||||
can continue and find further errors.
|
||||
|
||||
To print syntax fragments for debugging, you can use `span_note` together with
|
||||
`syntax::print::pprust::*_to_string`.
|
||||
|
||||
The example above produced an integer literal using `AstBuilder::expr_usize`.
|
||||
As an alternative to the `AstBuilder` trait, `libsyntax` provides a set of
|
||||
quasiquote macros. They are undocumented and very rough around the edges.
|
||||
However, the implementation may be a good starting point for an improved
|
||||
quasiquote as an ordinary plugin library.
|
||||
|
||||
|
||||
# Lint plugins
|
||||
|
||||
Plugins can extend [Rust's lint
|
||||
infrastructure](../reference/attributes.html#lint-check-attributes) with
|
||||
additional checks for code style, safety, etc. Now let's write a plugin
|
||||
[`lint_plugin_test.rs`](https://github.com/rust-lang/rust/blob/master/src/test/run-pass-fulldeps/auxiliary/lint_plugin_test.rs)
|
||||
that warns about any item named `lintme`.
|
||||
|
||||
```rust,ignore
|
||||
#![feature(plugin_registrar)]
|
||||
#![feature(box_syntax, rustc_private)]
|
||||
|
||||
extern crate syntax;
|
||||
|
||||
// Load rustc as a plugin to get macros
|
||||
#[macro_use]
|
||||
extern crate rustc;
|
||||
extern crate rustc_plugin;
|
||||
|
||||
use rustc::lint::{EarlyContext, LintContext, LintPass, EarlyLintPass,
|
||||
EarlyLintPassObject, LintArray};
|
||||
use rustc_plugin::Registry;
|
||||
use syntax::ast;
|
||||
|
||||
declare_lint!(TEST_LINT, Warn, "Warn about items named 'lintme'");
|
||||
|
||||
struct Pass;
|
||||
|
||||
impl LintPass for Pass {
|
||||
fn get_lints(&self) -> LintArray {
|
||||
lint_array!(TEST_LINT)
|
||||
}
|
||||
}
|
||||
|
||||
impl EarlyLintPass for Pass {
|
||||
fn check_item(&mut self, cx: &EarlyContext, it: &ast::Item) {
|
||||
if it.ident.name.as_str() == "lintme" {
|
||||
cx.span_lint(TEST_LINT, it.span, "item is named 'lintme'");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[plugin_registrar]
|
||||
pub fn plugin_registrar(reg: &mut Registry) {
|
||||
reg.register_early_lint_pass(box Pass as EarlyLintPassObject);
|
||||
}
|
||||
```
|
||||
|
||||
Then code like
|
||||
|
||||
```rust,ignore
|
||||
#![plugin(lint_plugin_test)]
|
||||
|
||||
fn lintme() { }
|
||||
```
|
||||
|
||||
will produce a compiler warning:
|
||||
|
||||
```txt
|
||||
foo.rs:4:1: 4:16 warning: item is named 'lintme', #[warn(test_lint)] on by default
|
||||
foo.rs:4 fn lintme() { }
|
||||
^~~~~~~~~~~~~~~
|
||||
```
|
||||
|
||||
The components of a lint plugin are:
|
||||
|
||||
* one or more `declare_lint!` invocations, which define static `Lint` structs;
|
||||
|
||||
* a struct holding any state needed by the lint pass (here, none);
|
||||
|
||||
* a `LintPass`
|
||||
implementation defining how to check each syntax element. A single
|
||||
`LintPass` may call `span_lint` for several different `Lint`s, but should
|
||||
register them all through the `get_lints` method.
|
||||
|
||||
Lint passes are syntax traversals, but they run at a late stage of compilation
|
||||
where type information is available. `rustc`'s [built-in
|
||||
lints](https://github.com/rust-lang/rust/blob/master/src/librustc/lint/builtin.rs)
|
||||
mostly use the same infrastructure as lint plugins, and provide examples of how
|
||||
to access type information.
|
||||
|
||||
Lints defined by plugins are controlled by the usual [attributes and compiler
|
||||
flags](../reference/attributes.html#lint-check-attributes), e.g.
|
||||
`#[allow(test_lint)]` or `-A test-lint`. These identifiers are derived from the
|
||||
first argument to `declare_lint!`, with appropriate case and punctuation
|
||||
conversion.
|
||||
|
||||
You can run `rustc -W help foo.rs` to see a list of lints known to `rustc`,
|
||||
including those provided by plugins loaded by `foo.rs`.
|
6
src/doc/unstable-book/src/prelude-import.md
Normal file
6
src/doc/unstable-book/src/prelude-import.md
Normal file
@ -0,0 +1,6 @@
|
||||
# `prelude_import`
|
||||
|
||||
The tracking issue for this feature is: None.
|
||||
|
||||
------------------------
|
||||
|
10
src/doc/unstable-book/src/proc-macro.md
Normal file
10
src/doc/unstable-book/src/proc-macro.md
Normal file
@ -0,0 +1,10 @@
|
||||
# `proc_macro`
|
||||
|
||||
The tracking issue for this feature is: [#38356]
|
||||
|
||||
[#38356]: https://github.com/rust-lang/rust/issues/38356
|
||||
|
||||
------------------------
|
||||
|
||||
|
||||
|
10
src/doc/unstable-book/src/pub-restricted.md
Normal file
10
src/doc/unstable-book/src/pub-restricted.md
Normal file
@ -0,0 +1,10 @@
|
||||
# `pub_restricted`
|
||||
|
||||
The tracking issue for this feature is: [#32409]
|
||||
|
||||
[#32409]: https://github.com/rust-lang/rust/issues/32409
|
||||
|
||||
------------------------
|
||||
|
||||
|
||||
|
10
src/doc/unstable-book/src/quote.md
Normal file
10
src/doc/unstable-book/src/quote.md
Normal file
@ -0,0 +1,10 @@
|
||||
# `quote`
|
||||
|
||||
The tracking issue for this feature is: [#29601]
|
||||
|
||||
[#29601]: https://github.com/rust-lang/rust/issues/29601
|
||||
|
||||
------------------------
|
||||
|
||||
|
||||
|
10
src/doc/unstable-book/src/relaxed-adts.md
Normal file
10
src/doc/unstable-book/src/relaxed-adts.md
Normal file
@ -0,0 +1,10 @@
|
||||
# `relaxed_adts`
|
||||
|
||||
The tracking issue for this feature is: [#35626]
|
||||
|
||||
[#35626]: https://github.com/rust-lang/rust/issues/35626
|
||||
|
||||
------------------------
|
||||
|
||||
|
||||
|
10
src/doc/unstable-book/src/repr-simd.md
Normal file
10
src/doc/unstable-book/src/repr-simd.md
Normal file
@ -0,0 +1,10 @@
|
||||
# `repr_simd`
|
||||
|
||||
The tracking issue for this feature is: [#27731]
|
||||
|
||||
[#27731]: https://github.com/rust-lang/rust/issues/27731
|
||||
|
||||
------------------------
|
||||
|
||||
|
||||
|
10
src/doc/unstable-book/src/rustc-attrs.md
Normal file
10
src/doc/unstable-book/src/rustc-attrs.md
Normal file
@ -0,0 +1,10 @@
|
||||
# `rustc_attrs`
|
||||
|
||||
The tracking issue for this feature is: [#29642]
|
||||
|
||||
[#29642]: https://github.com/rust-lang/rust/issues/29642
|
||||
|
||||
------------------------
|
||||
|
||||
|
||||
|
6
src/doc/unstable-book/src/rustc-diagnostic-macros.md
Normal file
6
src/doc/unstable-book/src/rustc-diagnostic-macros.md
Normal file
@ -0,0 +1,6 @@
|
||||
# `rustc_diagnostic_macros`
|
||||
|
||||
The tracking issue for this feature is: None.
|
||||
|
||||
------------------------
|
||||
|
6
src/doc/unstable-book/src/sanitizer-runtime.md
Normal file
6
src/doc/unstable-book/src/sanitizer-runtime.md
Normal file
@ -0,0 +1,6 @@
|
||||
# `sanitizer_runtime`
|
||||
|
||||
The tracking issue for this feature is: None.
|
||||
|
||||
------------------------
|
||||
|
10
src/doc/unstable-book/src/simd-ffi.md
Normal file
10
src/doc/unstable-book/src/simd-ffi.md
Normal file
@ -0,0 +1,10 @@
|
||||
# `simd_ffi`
|
||||
|
||||
The tracking issue for this feature is: [#27731]
|
||||
|
||||
[#27731]: https://github.com/rust-lang/rust/issues/27731
|
||||
|
||||
------------------------
|
||||
|
||||
|
||||
|
10
src/doc/unstable-book/src/simd.md
Normal file
10
src/doc/unstable-book/src/simd.md
Normal file
@ -0,0 +1,10 @@
|
||||
# `simd`
|
||||
|
||||
The tracking issue for this feature is: [#27731]
|
||||
|
||||
[#27731]: https://github.com/rust-lang/rust/issues/27731
|
||||
|
||||
------------------------
|
||||
|
||||
|
||||
|
27
src/doc/unstable-book/src/slice-patterns.md
Normal file
27
src/doc/unstable-book/src/slice-patterns.md
Normal file
@ -0,0 +1,27 @@
|
||||
# `slice_patterns`
|
||||
|
||||
The tracking issue for this feature is: [#23121]
|
||||
|
||||
[#23121]: https://github.com/rust-lang/rust/issues/23121
|
||||
|
||||
See also [`advanced_slice_patterns`](advanced-slice-patterns.html).
|
||||
|
||||
------------------------
|
||||
|
||||
|
||||
If you want to match against a slice or array, you can use `&` with the
|
||||
`slice_patterns` feature:
|
||||
|
||||
```rust
|
||||
#![feature(slice_patterns)]
|
||||
|
||||
fn main() {
|
||||
let v = vec!["match_this", "1"];
|
||||
|
||||
match &v[..] {
|
||||
&["match_this", second] => println!("The second element is {}", second),
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
```
|
||||
|
8
src/doc/unstable-book/src/specialization.md
Normal file
8
src/doc/unstable-book/src/specialization.md
Normal file
@ -0,0 +1,8 @@
|
||||
# `specialization`
|
||||
|
||||
The tracking issue for this feature is: [#31844]
|
||||
|
||||
------------------------
|
||||
|
||||
|
||||
|
6
src/doc/unstable-book/src/staged-api.md
Normal file
6
src/doc/unstable-book/src/staged-api.md
Normal file
@ -0,0 +1,6 @@
|
||||
# `staged_api`
|
||||
|
||||
The tracking issue for this feature is: None.
|
||||
|
||||
------------------------
|
||||
|
10
src/doc/unstable-book/src/start.md
Normal file
10
src/doc/unstable-book/src/start.md
Normal file
@ -0,0 +1,10 @@
|
||||
# `start`
|
||||
|
||||
The tracking issue for this feature is: [#29633]
|
||||
|
||||
[#29633]: https://github.com/rust-lang/rust/issues/29633
|
||||
|
||||
------------------------
|
||||
|
||||
|
||||
|
10
src/doc/unstable-book/src/static-nobundle.md
Normal file
10
src/doc/unstable-book/src/static-nobundle.md
Normal file
@ -0,0 +1,10 @@
|
||||
# `static_nobundle`
|
||||
|
||||
The tracking issue for this feature is: [#37403]
|
||||
|
||||
[#37403]: https://github.com/rust-lang/rust/issues/37403
|
||||
|
||||
------------------------
|
||||
|
||||
|
||||
|
10
src/doc/unstable-book/src/static-recursion.md
Normal file
10
src/doc/unstable-book/src/static-recursion.md
Normal file
@ -0,0 +1,10 @@
|
||||
# `static_recursion`
|
||||
|
||||
The tracking issue for this feature is: [#29719]
|
||||
|
||||
[#29719]: https://github.com/rust-lang/rust/issues/29719
|
||||
|
||||
------------------------
|
||||
|
||||
|
||||
|
10
src/doc/unstable-book/src/stmt-expr-attributes.md
Normal file
10
src/doc/unstable-book/src/stmt-expr-attributes.md
Normal file
@ -0,0 +1,10 @@
|
||||
# `stmt_expr_attributes`
|
||||
|
||||
The tracking issue for this feature is: [#15701]
|
||||
|
||||
[#15701]: https://github.com/rust-lang/rust/issues/15701
|
||||
|
||||
------------------------
|
||||
|
||||
|
||||
|
10
src/doc/unstable-book/src/struct-field-attributes.md
Normal file
10
src/doc/unstable-book/src/struct-field-attributes.md
Normal file
@ -0,0 +1,10 @@
|
||||
# `struct_field_attributes`
|
||||
|
||||
The tracking issue for this feature is: [#38814]
|
||||
|
||||
[#38814]: https://github.com/rust-lang/rust/issues/38814
|
||||
|
||||
------------------------
|
||||
|
||||
|
||||
|
10
src/doc/unstable-book/src/structural-match.md
Normal file
10
src/doc/unstable-book/src/structural-match.md
Normal file
@ -0,0 +1,10 @@
|
||||
# `structural_match`
|
||||
|
||||
The tracking issue for this feature is: [#31434]
|
||||
|
||||
[#31434]: https://github.com/rust-lang/rust/issues/31434
|
||||
|
||||
------------------------
|
||||
|
||||
|
||||
|
6
src/doc/unstable-book/src/target-feature.md
Normal file
6
src/doc/unstable-book/src/target-feature.md
Normal file
@ -0,0 +1,6 @@
|
||||
# `target_feature`
|
||||
|
||||
The tracking issue for this feature is: None.
|
||||
|
||||
------------------------
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user