diff --git a/src/bootstrap/step.rs b/src/bootstrap/step.rs index 36738b81c189e..fe183c5bce8e8 100644 --- a/src/bootstrap/step.rs +++ b/src/bootstrap/step.rs @@ -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") diff --git a/src/doc/book/src/README.md b/src/doc/book/src/README.md index 9162642b1cc62..ade4d52c1eb31 100644 --- a/src/doc/book/src/README.md +++ b/src/doc/book/src/README.md @@ -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 diff --git a/src/doc/book/src/SUMMARY.md b/src/doc/book/src/SUMMARY.md index 74b9b7fa5b292..c3763cdf9d6d7 100644 --- a/src/doc/book/src/SUMMARY.md +++ b/src/doc/book/src/SUMMARY.md @@ -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) diff --git a/src/doc/book/src/advanced-linking.md b/src/doc/book/src/advanced-linking.md deleted file mode 100644 index a882d6d2ebe07..0000000000000 --- a/src/doc/book/src/advanced-linking.md +++ /dev/null @@ -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. diff --git a/src/doc/book/src/box-syntax-and-patterns.md b/src/doc/book/src/box-syntax-and-patterns.md deleted file mode 100644 index f03e881f47404..0000000000000 --- a/src/doc/book/src/box-syntax-and-patterns.md +++ /dev/null @@ -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) -> Box { - 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 { - *x -} - -fn main() { - let x = Box::new(BigStruct { - one: 1, - two: 2, - one_hundred: 100, - }); - - let y: Box = 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`. - -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. diff --git a/src/doc/book/src/casting-between-types.md b/src/doc/book/src/casting-between-types.md index 853fb1ec25417..26cd718475eab 100644 --- a/src/doc/book/src/casting-between-types.md +++ b/src/doc/book/src/casting-between-types.md @@ -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`, diff --git a/src/doc/book/src/conditional-compilation.md b/src/doc/book/src/conditional-compilation.md index 938c1c5132698..0562e9fc430f6 100644 --- a/src/doc/book/src/conditional-compilation.md +++ b/src/doc/book/src/conditional-compilation.md @@ -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. diff --git a/src/doc/book/src/lang-items.md b/src/doc/book/src/lang-items.md deleted file mode 100644 index 9bd64d3817955..0000000000000 --- a/src/doc/book/src/lang-items.md +++ /dev/null @@ -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(*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(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. diff --git a/src/doc/book/src/macros.md b/src/doc/book/src/macros.md index 93f63ddc0a562..fa8e8975a5b01 100644 --- a/src/doc/book/src/macros.md +++ b/src/doc/book/src/macros.md @@ -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. diff --git a/src/doc/book/src/nightly-rust.md b/src/doc/book/src/nightly-rust.md deleted file mode 100644 index 5dfaa9e0fa800..0000000000000 --- a/src/doc/book/src/nightly-rust.md +++ /dev/null @@ -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 - diff --git a/src/doc/book/src/unsafe.md b/src/doc/book/src/unsafe.md index e90a4b1c268ca..9bf59fe2abdc3 100644 --- a/src/doc/book/src/unsafe.md +++ b/src/doc/book/src/unsafe.md @@ -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 diff --git a/src/doc/book/src/using-rust-without-the-standard-library.md b/src/doc/book/src/using-rust-without-the-standard-library.md index 8458f9314f926..709d10f4e4791 100644 --- a/src/doc/book/src/using-rust-without-the-standard-library.md +++ b/src/doc/book/src/using-rust-without-the-standard-library.md @@ -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: diff --git a/src/doc/guide-plugins.md b/src/doc/guide-plugins.md index 742433b99ac5f..1ba28c0117db5 100644 --- a/src/doc/guide-plugins.md +++ b/src/doc/guide-plugins.md @@ -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). diff --git a/src/doc/reference/src/attributes.md b/src/doc/reference/src/attributes.md index da43e1cc057eb..8f3fdbf3679c1 100644 --- a/src/doc/reference/src/attributes.md +++ b/src/doc/reference/src/attributes.md @@ -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} diff --git a/src/doc/reference/src/macros.md b/src/doc/reference/src/macros.md index 9ec5f2d6945e5..d64c40dcad835 100644 --- a/src/doc/reference/src/macros.md +++ b/src/doc/reference/src/macros.md @@ -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 diff --git a/src/doc/unstable-book/.gitignore b/src/doc/unstable-book/.gitignore new file mode 100644 index 0000000000000..7585238efedfc --- /dev/null +++ b/src/doc/unstable-book/.gitignore @@ -0,0 +1 @@ +book diff --git a/src/doc/unstable-book/src/SUMMARY.md b/src/doc/unstable-book/src/SUMMARY.md new file mode 100644 index 0000000000000..ee8ae9a9839e9 --- /dev/null +++ b/src/doc/unstable-book/src/SUMMARY.md @@ -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) diff --git a/src/doc/unstable-book/src/abi-msp430-interrupt.md b/src/doc/unstable-book/src/abi-msp430-interrupt.md new file mode 100644 index 0000000000000..9b2c7f298979d --- /dev/null +++ b/src/doc/unstable-book/src/abi-msp430-interrupt.md @@ -0,0 +1,7 @@ +# `abi_msp430_interrupt` + +The tracking issue for this feature is: [#38487] + +[#38487]: https://github.com/rust-lang/rust/issues/38487 + +------------------------ diff --git a/src/doc/unstable-book/src/abi-ptx.md b/src/doc/unstable-book/src/abi-ptx.md new file mode 100644 index 0000000000000..9c1b8868aceb4 --- /dev/null +++ b/src/doc/unstable-book/src/abi-ptx.md @@ -0,0 +1,5 @@ +# `abi_ptx` + +The tracking issue for this feature is: None. + +------------------------ diff --git a/src/doc/unstable-book/src/abi-sysv64.md b/src/doc/unstable-book/src/abi-sysv64.md new file mode 100644 index 0000000000000..27f61d56342cf --- /dev/null +++ b/src/doc/unstable-book/src/abi-sysv64.md @@ -0,0 +1,7 @@ +# `abi_sysv64` + +The tracking issue for this feature is: [#36167] + +[#36167]: https://github.com/rust-lang/rust/issues/36167 + +------------------------ diff --git a/src/doc/unstable-book/src/abi-unadjusted.md b/src/doc/unstable-book/src/abi-unadjusted.md new file mode 100644 index 0000000000000..2e3113abdbf2b --- /dev/null +++ b/src/doc/unstable-book/src/abi-unadjusted.md @@ -0,0 +1,6 @@ +# `abi_unadjusted` + +The tracking issue for this feature is: none. + +------------------------ + diff --git a/src/doc/unstable-book/src/abi-vectorcall.md b/src/doc/unstable-book/src/abi-vectorcall.md new file mode 100644 index 0000000000000..3e36b1569fd4a --- /dev/null +++ b/src/doc/unstable-book/src/abi-vectorcall.md @@ -0,0 +1,7 @@ +# `abi_vectorcall` + +The tracking issue for this feature is: none. + +------------------------ + + diff --git a/src/doc/book/src/slice-patterns.md b/src/doc/unstable-book/src/advanced-slice-patterns.md similarity index 67% rename from src/doc/book/src/slice-patterns.md rename to src/doc/unstable-book/src/advanced-slice-patterns.md index 3f7398dde5e20..30d22ca8208bf 100644 --- a/src/doc/book/src/slice-patterns.md +++ b/src/doc/unstable-book/src/advanced-slice-patterns.md @@ -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 diff --git a/src/doc/unstable-book/src/alloc-jemalloc.md b/src/doc/unstable-book/src/alloc-jemalloc.md new file mode 100644 index 0000000000000..9bffa2ff99bf3 --- /dev/null +++ b/src/doc/unstable-book/src/alloc-jemalloc.md @@ -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() {} +``` + diff --git a/src/doc/unstable-book/src/alloc-system.md b/src/doc/unstable-book/src/alloc-system.md new file mode 100644 index 0000000000000..6fa89179d8e11 --- /dev/null +++ b/src/doc/unstable-book/src/alloc-system.md @@ -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() {} +``` + diff --git a/src/doc/book/src/custom-allocators.md b/src/doc/unstable-book/src/allocator.md similarity index 61% rename from src/doc/book/src/custom-allocators.md rename to src/doc/unstable-book/src/allocator.md index 154b5f0f4e256..7261641698f48 100644 --- a/src/doc/book/src/custom-allocators.md +++ b/src/doc/unstable-book/src/allocator.md @@ -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. + + diff --git a/src/doc/unstable-book/src/allow-internal-unstable.md b/src/doc/unstable-book/src/allow-internal-unstable.md new file mode 100644 index 0000000000000..74709ad5aeb4d --- /dev/null +++ b/src/doc/unstable-book/src/allow-internal-unstable.md @@ -0,0 +1,6 @@ +# `allow_internal_unstable` + +The tracking issue for this feature is: None. + +------------------------ + diff --git a/src/doc/book/src/inline-assembly.md b/src/doc/unstable-book/src/asm.md similarity index 97% rename from src/doc/book/src/inline-assembly.md rename to src/doc/unstable-book/src/asm.md index 4262289acbfde..032d9d8124026 100644 --- a/src/doc/book/src/inline-assembly.md +++ b/src/doc/unstable-book/src/asm.md @@ -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 + diff --git a/src/doc/book/src/associated-constants.md b/src/doc/unstable-book/src/associated-consts.md similarity index 88% rename from src/doc/book/src/associated-constants.md rename to src/doc/unstable-book/src/associated-consts.md index 61bad3d394895..d661108e7d95e 100644 --- a/src/doc/book/src/associated-constants.md +++ b/src/doc/unstable-book/src/associated-consts.md @@ -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: diff --git a/src/doc/unstable-book/src/associated-type-defaults.md b/src/doc/unstable-book/src/associated-type-defaults.md new file mode 100644 index 0000000000000..56cc8a5b3060a --- /dev/null +++ b/src/doc/unstable-book/src/associated-type-defaults.md @@ -0,0 +1,10 @@ +# `associated_type_defaults` + +The tracking issue for this feature is: [#29661] + +[#29661]: https://github.com/rust-lang/rust/issues/29661 + +------------------------ + + + diff --git a/src/doc/unstable-book/src/attr-literals.md b/src/doc/unstable-book/src/attr-literals.md new file mode 100644 index 0000000000000..67eee214a4f24 --- /dev/null +++ b/src/doc/unstable-book/src/attr-literals.md @@ -0,0 +1,10 @@ +# `attr_literals` + +The tracking issue for this feature is: [#34981] + +[#34981]: https://github.com/rust-lang/rust/issues/34981 + +------------------------ + + + diff --git a/src/doc/unstable-book/src/box-patterns.md b/src/doc/unstable-book/src/box-patterns.md new file mode 100644 index 0000000000000..86346364a7135 --- /dev/null +++ b/src/doc/unstable-book/src/box-patterns.md @@ -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`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!() + } +} +``` diff --git a/src/doc/unstable-book/src/box-syntax.md b/src/doc/unstable-book/src/box-syntax.md new file mode 100644 index 0000000000000..47aade0d04563 --- /dev/null +++ b/src/doc/unstable-book/src/box-syntax.md @@ -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; +} +``` diff --git a/src/doc/unstable-book/src/cfg-target-feature.md b/src/doc/unstable-book/src/cfg-target-feature.md new file mode 100644 index 0000000000000..ddd88bdc2cb17 --- /dev/null +++ b/src/doc/unstable-book/src/cfg-target-feature.md @@ -0,0 +1,10 @@ +# `cfg_target_feature` + +The tracking issue for this feature is: [#29717] + +[#29717]: https://github.com/rust-lang/rust/issues/29717 + +------------------------ + + + diff --git a/src/doc/unstable-book/src/cfg-target-has-atomic.md b/src/doc/unstable-book/src/cfg-target-has-atomic.md new file mode 100644 index 0000000000000..7496e42e1cd84 --- /dev/null +++ b/src/doc/unstable-book/src/cfg-target-has-atomic.md @@ -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 + +------------------------ + + + diff --git a/src/doc/unstable-book/src/cfg-target-thread-local.md b/src/doc/unstable-book/src/cfg-target-thread-local.md new file mode 100644 index 0000000000000..a5adb38db3df0 --- /dev/null +++ b/src/doc/unstable-book/src/cfg-target-thread-local.md @@ -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 + +------------------------ + + + diff --git a/src/doc/unstable-book/src/cfg-target-vendor.md b/src/doc/unstable-book/src/cfg-target-vendor.md new file mode 100644 index 0000000000000..ddd88bdc2cb17 --- /dev/null +++ b/src/doc/unstable-book/src/cfg-target-vendor.md @@ -0,0 +1,10 @@ +# `cfg_target_feature` + +The tracking issue for this feature is: [#29717] + +[#29717]: https://github.com/rust-lang/rust/issues/29717 + +------------------------ + + + diff --git a/src/doc/unstable-book/src/compiler-builtins.md b/src/doc/unstable-book/src/compiler-builtins.md new file mode 100644 index 0000000000000..3ec3cba257a99 --- /dev/null +++ b/src/doc/unstable-book/src/compiler-builtins.md @@ -0,0 +1,6 @@ +# `compiler_builtins` + +The tracking issue for this feature is: None. + +------------------------ + diff --git a/src/doc/unstable-book/src/concat-idents.md b/src/doc/unstable-book/src/concat-idents.md new file mode 100644 index 0000000000000..c9a48293dba68 --- /dev/null +++ b/src/doc/unstable-book/src/concat-idents.md @@ -0,0 +1,10 @@ +# `concat_idents` + +The tracking issue for this feature is: [#29599] + +[#29599]: https://github.com/rust-lang/rust/issues/29599 + +------------------------ + + + diff --git a/src/doc/unstable-book/src/conservative-impl-trait.md b/src/doc/unstable-book/src/conservative-impl-trait.md new file mode 100644 index 0000000000000..7d8bda439bd34 --- /dev/null +++ b/src/doc/unstable-book/src/conservative-impl-trait.md @@ -0,0 +1,10 @@ +# `conservative_impl_trait` + +The tracking issue for this feature is: [#34511] + +[#34511]: https://github.com/rust-lang/rust/issues/34511 + +------------------------ + + + diff --git a/src/doc/unstable-book/src/const-fn.md b/src/doc/unstable-book/src/const-fn.md new file mode 100644 index 0000000000000..9b7942c408a24 --- /dev/null +++ b/src/doc/unstable-book/src/const-fn.md @@ -0,0 +1,10 @@ +# `const_fn` + +The tracking issue for this feature is: [#24111] + +[#24111]: https://github.com/rust-lang/rust/issues/24111 + +------------------------ + + + diff --git a/src/doc/unstable-book/src/const-indexing.md b/src/doc/unstable-book/src/const-indexing.md new file mode 100644 index 0000000000000..bd92b0b1b478f --- /dev/null +++ b/src/doc/unstable-book/src/const-indexing.md @@ -0,0 +1,10 @@ +# `const_indexing` + +The tracking issue for this feature is: [#29947] + +[#29947]: https://github.com/rust-lang/rust/issues/29947 + +------------------------ + + + diff --git a/src/doc/unstable-book/src/custom-attribute.md b/src/doc/unstable-book/src/custom-attribute.md new file mode 100644 index 0000000000000..838f09670d2cd --- /dev/null +++ b/src/doc/unstable-book/src/custom-attribute.md @@ -0,0 +1,10 @@ +# `custom_attribute` + +The tracking issue for this feature is: [#29642] + +[#29642]: https://github.com/rust-lang/rust/issues/29642 + +------------------------ + + + diff --git a/src/doc/unstable-book/src/custom-derive.md b/src/doc/unstable-book/src/custom-derive.md new file mode 100644 index 0000000000000..d5fdd2b708bb8 --- /dev/null +++ b/src/doc/unstable-book/src/custom-derive.md @@ -0,0 +1,10 @@ +# `custom_derive` + +The tracking issue for this feature is: [#29644] + +[#29644]: https://github.com/rust-lang/rust/issues/29644 + +------------------------ + + + diff --git a/src/doc/unstable-book/src/default-type-parameter-fallback.md b/src/doc/unstable-book/src/default-type-parameter-fallback.md new file mode 100644 index 0000000000000..fd16dbf898537 --- /dev/null +++ b/src/doc/unstable-book/src/default-type-parameter-fallback.md @@ -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 + +------------------------ + + + diff --git a/src/doc/unstable-book/src/drop-types-in-const.md b/src/doc/unstable-book/src/drop-types-in-const.md new file mode 100644 index 0000000000000..b3367d0df4459 --- /dev/null +++ b/src/doc/unstable-book/src/drop-types-in-const.md @@ -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 + +------------------------ + + + diff --git a/src/doc/unstable-book/src/dropck-eyepatch.md b/src/doc/unstable-book/src/dropck-eyepatch.md new file mode 100644 index 0000000000000..2f189e9b6454a --- /dev/null +++ b/src/doc/unstable-book/src/dropck-eyepatch.md @@ -0,0 +1,10 @@ +# `dropck_eyepatch` + +The tracking issue for this feature is: [#34761] + +[#34761]: https://github.com/rust-lang/rust/issues/34761 + +------------------------ + + + diff --git a/src/doc/unstable-book/src/dropck-parametricity.md b/src/doc/unstable-book/src/dropck-parametricity.md new file mode 100644 index 0000000000000..c5ae721954b82 --- /dev/null +++ b/src/doc/unstable-book/src/dropck-parametricity.md @@ -0,0 +1,10 @@ +# `dropck_parametricity` + +The tracking issue for this feature is: [#28498] + +[#28498]: https://github.com/rust-lang/rust/issues/28498 + +------------------------ + + + diff --git a/src/doc/unstable-book/src/exclusive-range-pattern.md b/src/doc/unstable-book/src/exclusive-range-pattern.md new file mode 100644 index 0000000000000..b669ce83132d4 --- /dev/null +++ b/src/doc/unstable-book/src/exclusive-range-pattern.md @@ -0,0 +1,10 @@ +# `exclusive_range_pattern` + +The tracking issue for this feature is: [#37854] + +[#37854]: https://github.com/rust-lang/rust/issues/37854 + +------------------------ + + + diff --git a/src/doc/unstable-book/src/field-init-shorthand.md b/src/doc/unstable-book/src/field-init-shorthand.md new file mode 100644 index 0000000000000..e737dbaa4ec02 --- /dev/null +++ b/src/doc/unstable-book/src/field-init-shorthand.md @@ -0,0 +1,10 @@ +# `field_init_shorthand` + +The tracking issue for this feature is: [#37340] + +[#37340]: https://github.com/rust-lang/rust/issues/37340 + +------------------------ + + + diff --git a/src/doc/unstable-book/src/fundamental.md b/src/doc/unstable-book/src/fundamental.md new file mode 100644 index 0000000000000..a068dadf95d12 --- /dev/null +++ b/src/doc/unstable-book/src/fundamental.md @@ -0,0 +1,10 @@ +# `fundamental` + +The tracking issue for this feature is: [#29635] + +[#29635]: https://github.com/rust-lang/rust/issues/29635 + +------------------------ + + + diff --git a/src/doc/unstable-book/src/generic-param-attrs.md b/src/doc/unstable-book/src/generic-param-attrs.md new file mode 100644 index 0000000000000..ba49c850e4d60 --- /dev/null +++ b/src/doc/unstable-book/src/generic-param-attrs.md @@ -0,0 +1,10 @@ +# `generic_param_attrs` + +The tracking issue for this feature is: [#34761] + +[#34761]: https://github.com/rust-lang/rust/issues/34761 + +------------------------ + + + diff --git a/src/doc/unstable-book/src/i128-type.md b/src/doc/unstable-book/src/i128-type.md new file mode 100644 index 0000000000000..ffcf45feb2ad7 --- /dev/null +++ b/src/doc/unstable-book/src/i128-type.md @@ -0,0 +1,10 @@ +# `i128_type` + +The tracking issue for this feature is: [#35118] + +[#35118]: https://github.com/rust-lang/rust/issues/35118 + +------------------------ + + + diff --git a/src/doc/unstable-book/src/inclusive-range-syntax.md b/src/doc/unstable-book/src/inclusive-range-syntax.md new file mode 100644 index 0000000000000..74d85536399d7 --- /dev/null +++ b/src/doc/unstable-book/src/inclusive-range-syntax.md @@ -0,0 +1,10 @@ +# `inclusive_range_syntax` + +The tracking issue for this feature is: [#28237] + +[#28237]: https://github.com/rust-lang/rust/issues/28237 + +------------------------ + + + diff --git a/src/doc/book/src/intrinsics.md b/src/doc/unstable-book/src/intrinsics.md similarity index 65% rename from src/doc/book/src/intrinsics.md rename to src/doc/unstable-book/src/intrinsics.md index e1edce3e80f71..bc35c2a030533 100644 --- a/src/doc/book/src/intrinsics.md +++ b/src/doc/unstable-book/src/intrinsics.md @@ -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 diff --git a/src/doc/book/src/no-stdlib.md b/src/doc/unstable-book/src/lang-items.md similarity index 56% rename from src/doc/book/src/no-stdlib.md rename to src/doc/unstable-book/src/lang-items.md index dcb0fbc800534..375b8bd6b8224 100644 --- a/src/doc/book/src/no-stdlib.md +++ b/src/doc/unstable-book/src/lang-items.md @@ -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(*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(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] diff --git a/src/doc/unstable-book/src/link-args.md b/src/doc/unstable-book/src/link-args.md new file mode 100644 index 0000000000000..2507197661a9d --- /dev/null +++ b/src/doc/unstable-book/src/link-args.md @@ -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. diff --git a/src/doc/unstable-book/src/link-cfg.md b/src/doc/unstable-book/src/link-cfg.md new file mode 100644 index 0000000000000..7393d0628e4f5 --- /dev/null +++ b/src/doc/unstable-book/src/link-cfg.md @@ -0,0 +1,10 @@ +# `link_cfg` + +The tracking issue for this feature is: [#37406] + +[#37406]: https://github.com/rust-lang/rust/issues/37406 + +------------------------ + + + diff --git a/src/doc/unstable-book/src/link-llvm-intrinsics.md b/src/doc/unstable-book/src/link-llvm-intrinsics.md new file mode 100644 index 0000000000000..ba639cb57fc6d --- /dev/null +++ b/src/doc/unstable-book/src/link-llvm-intrinsics.md @@ -0,0 +1,10 @@ +# `link_llvm_intrinsics` + +The tracking issue for this feature is: [#29602] + +[#29602]: https://github.com/rust-lang/rust/issues/29602 + +------------------------ + + + diff --git a/src/doc/unstable-book/src/linkage.md b/src/doc/unstable-book/src/linkage.md new file mode 100644 index 0000000000000..5773d28a00ecc --- /dev/null +++ b/src/doc/unstable-book/src/linkage.md @@ -0,0 +1,10 @@ +# `linkage` + +The tracking issue for this feature is: [#29603] + +[#29603]: https://github.com/rust-lang/rust/issues/29603 + +------------------------ + + + diff --git a/src/doc/unstable-book/src/log-syntax.md b/src/doc/unstable-book/src/log-syntax.md new file mode 100644 index 0000000000000..b13f5ccfd9179 --- /dev/null +++ b/src/doc/unstable-book/src/log-syntax.md @@ -0,0 +1,10 @@ +# `log_syntax` + +The tracking issue for this feature is: [#29598] + +[#29598]: https://github.com/rust-lang/rust/issues/29598 + +------------------------ + + + diff --git a/src/doc/unstable-book/src/loop-break-value.md b/src/doc/unstable-book/src/loop-break-value.md new file mode 100644 index 0000000000000..54d6e62ce4c52 --- /dev/null +++ b/src/doc/unstable-book/src/loop-break-value.md @@ -0,0 +1,10 @@ +# `loop_break_value` + +The tracking issue for this feature is: [#37339] + +[#37339]: https://github.com/rust-lang/rust/issues/37339 + +------------------------ + + + diff --git a/src/doc/unstable-book/src/macro-reexport.md b/src/doc/unstable-book/src/macro-reexport.md new file mode 100644 index 0000000000000..32ffa3b4c31e5 --- /dev/null +++ b/src/doc/unstable-book/src/macro-reexport.md @@ -0,0 +1,10 @@ +# `macro_reexport` + +The tracking issue for this feature is: [#29638] + +[#29638]: https://github.com/rust-lang/rust/issues/29638 + +------------------------ + + + diff --git a/src/doc/unstable-book/src/main.md b/src/doc/unstable-book/src/main.md new file mode 100644 index 0000000000000..579aabfff88b9 --- /dev/null +++ b/src/doc/unstable-book/src/main.md @@ -0,0 +1,10 @@ +# `main` + +The tracking issue for this feature is: [#29634] + +[#29634]: https://github.com/rust-lang/rust/issues/29634 + +------------------------ + + + diff --git a/src/doc/unstable-book/src/naked-functions.md b/src/doc/unstable-book/src/naked-functions.md new file mode 100644 index 0000000000000..e56ce4770aab0 --- /dev/null +++ b/src/doc/unstable-book/src/naked-functions.md @@ -0,0 +1,10 @@ +# `naked_functions` + +The tracking issue for this feature is: [#32408] + +[#32408]: https://github.com/rust-lang/rust/issues/32408 + +------------------------ + + + diff --git a/src/doc/unstable-book/src/needs-allocator.md b/src/doc/unstable-book/src/needs-allocator.md new file mode 100644 index 0000000000000..22aa10b2183cb --- /dev/null +++ b/src/doc/unstable-book/src/needs-allocator.md @@ -0,0 +1,10 @@ +# `needs_allocator` + +The tracking issue for this feature is: [#27389] + +[#27389]: https://github.com/rust-lang/rust/issues/27389 + +------------------------ + + + diff --git a/src/doc/unstable-book/src/needs-panic-runtime.md b/src/doc/unstable-book/src/needs-panic-runtime.md new file mode 100644 index 0000000000000..627c946c1bb27 --- /dev/null +++ b/src/doc/unstable-book/src/needs-panic-runtime.md @@ -0,0 +1,10 @@ +# `needs_panic_runtime` + +The tracking issue for this feature is: [#32837] + +[#32837]: https://github.com/rust-lang/rust/issues/32837 + +------------------------ + + + diff --git a/src/doc/unstable-book/src/never-type.md b/src/doc/unstable-book/src/never-type.md new file mode 100644 index 0000000000000..3b3729a4b21d7 --- /dev/null +++ b/src/doc/unstable-book/src/never-type.md @@ -0,0 +1,10 @@ +# `never_type` + +The tracking issue for this feature is: [#35121] + +[#35121]: https://github.com/rust-lang/rust/issues/35121 + +------------------------ + + + diff --git a/src/doc/unstable-book/src/no-core.md b/src/doc/unstable-book/src/no-core.md new file mode 100644 index 0000000000000..6238753447c9c --- /dev/null +++ b/src/doc/unstable-book/src/no-core.md @@ -0,0 +1,10 @@ +# `no_core` + +The tracking issue for this feature is: [#29639] + +[#29639]: https://github.com/rust-lang/rust/issues/29639 + +------------------------ + + + diff --git a/src/doc/unstable-book/src/no-debug.md b/src/doc/unstable-book/src/no-debug.md new file mode 100644 index 0000000000000..7536ed9d4e106 --- /dev/null +++ b/src/doc/unstable-book/src/no-debug.md @@ -0,0 +1,10 @@ +# `no_debug` + +The tracking issue for this feature is: [#29721] + +[#29721]: https://github.com/rust-lang/rust/issues/29721 + +------------------------ + + + diff --git a/src/doc/unstable-book/src/non-ascii-idents.md b/src/doc/unstable-book/src/non-ascii-idents.md new file mode 100644 index 0000000000000..f426022ab3a51 --- /dev/null +++ b/src/doc/unstable-book/src/non-ascii-idents.md @@ -0,0 +1,10 @@ +# `non_ascii_idents` + +The tracking issue for this feature is: [#28979] + +[#28979]: https://github.com/rust-lang/rust/issues/28979 + +------------------------ + + + diff --git a/src/doc/unstable-book/src/omit-gdb-pretty-printer-section.md b/src/doc/unstable-book/src/omit-gdb-pretty-printer-section.md new file mode 100644 index 0000000000000..d8ac520fcb5e2 --- /dev/null +++ b/src/doc/unstable-book/src/omit-gdb-pretty-printer-section.md @@ -0,0 +1,6 @@ +# `omit_gdb_pretty_printer_section` + +The tracking issue for this feature is: None. + +------------------------ + diff --git a/src/doc/unstable-book/src/on-unimplemented.md b/src/doc/unstable-book/src/on-unimplemented.md new file mode 100644 index 0000000000000..81f284d0a6a3e --- /dev/null +++ b/src/doc/unstable-book/src/on-unimplemented.md @@ -0,0 +1,10 @@ +# `on_unimplemented` + +The tracking issue for this feature is: [#29628] + +[#29628]: https://github.com/rust-lang/rust/issues/29628 + +------------------------ + + + diff --git a/src/doc/unstable-book/src/optin-builtin-traits.md b/src/doc/unstable-book/src/optin-builtin-traits.md new file mode 100644 index 0000000000000..0b2d60accd59a --- /dev/null +++ b/src/doc/unstable-book/src/optin-builtin-traits.md @@ -0,0 +1,9 @@ +# `optin_builtin_traits` + +The tracking issue for this feature is: [#13231] + +[#13231]: https://github.com/rust-lang/rust/issues/13231 + +------------------------ + + diff --git a/src/doc/unstable-book/src/panic-runtime.md b/src/doc/unstable-book/src/panic-runtime.md new file mode 100644 index 0000000000000..65b067e829613 --- /dev/null +++ b/src/doc/unstable-book/src/panic-runtime.md @@ -0,0 +1,10 @@ +# `panic_runtime` + +The tracking issue for this feature is: [#32837] + +[#32837]: https://github.com/rust-lang/rust/issues/32837 + +------------------------ + + + diff --git a/src/doc/unstable-book/src/placement-in-syntax.md b/src/doc/unstable-book/src/placement-in-syntax.md new file mode 100644 index 0000000000000..da12559a01b86 --- /dev/null +++ b/src/doc/unstable-book/src/placement-in-syntax.md @@ -0,0 +1,10 @@ +# `placement_in_syntax` + +The tracking issue for this feature is: [#27779] + +[#27779]: https://github.com/rust-lang/rust/issues/27779 + +------------------------ + + + diff --git a/src/doc/unstable-book/src/platform-intrinsics.md b/src/doc/unstable-book/src/platform-intrinsics.md new file mode 100644 index 0000000000000..377ac8f7342ef --- /dev/null +++ b/src/doc/unstable-book/src/platform-intrinsics.md @@ -0,0 +1,10 @@ +# `platform_intrinsics` + +The tracking issue for this feature is: [#27731] + +[#27731]: https://github.com/rust-lang/rust/issues/27731 + +------------------------ + + + diff --git a/src/doc/unstable-book/src/plugin-registrar.md b/src/doc/unstable-book/src/plugin-registrar.md new file mode 100644 index 0000000000000..ca3738bd93f83 --- /dev/null +++ b/src/doc/unstable-book/src/plugin-registrar.md @@ -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 + +------------------------ diff --git a/src/doc/unstable-book/src/plugin.md b/src/doc/unstable-book/src/plugin.md new file mode 100644 index 0000000000000..ca69b7084d3e6 --- /dev/null +++ b/src/doc/unstable-book/src/plugin.md @@ -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 { + + 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 { + + let mut parser = cx.new_parser_from_tts(args); + + let expr: P = 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`. diff --git a/src/doc/unstable-book/src/prelude-import.md b/src/doc/unstable-book/src/prelude-import.md new file mode 100644 index 0000000000000..75dae5cfb7401 --- /dev/null +++ b/src/doc/unstable-book/src/prelude-import.md @@ -0,0 +1,6 @@ +# `prelude_import` + +The tracking issue for this feature is: None. + +------------------------ + diff --git a/src/doc/unstable-book/src/proc-macro.md b/src/doc/unstable-book/src/proc-macro.md new file mode 100644 index 0000000000000..f8b53bd5a2fd3 --- /dev/null +++ b/src/doc/unstable-book/src/proc-macro.md @@ -0,0 +1,10 @@ +# `proc_macro` + +The tracking issue for this feature is: [#38356] + +[#38356]: https://github.com/rust-lang/rust/issues/38356 + +------------------------ + + + diff --git a/src/doc/unstable-book/src/pub-restricted.md b/src/doc/unstable-book/src/pub-restricted.md new file mode 100644 index 0000000000000..730461813cbec --- /dev/null +++ b/src/doc/unstable-book/src/pub-restricted.md @@ -0,0 +1,10 @@ +# `pub_restricted` + +The tracking issue for this feature is: [#32409] + +[#32409]: https://github.com/rust-lang/rust/issues/32409 + +------------------------ + + + diff --git a/src/doc/unstable-book/src/quote.md b/src/doc/unstable-book/src/quote.md new file mode 100644 index 0000000000000..b4e078d920c4e --- /dev/null +++ b/src/doc/unstable-book/src/quote.md @@ -0,0 +1,10 @@ +# `quote` + +The tracking issue for this feature is: [#29601] + +[#29601]: https://github.com/rust-lang/rust/issues/29601 + +------------------------ + + + diff --git a/src/doc/unstable-book/src/relaxed-adts.md b/src/doc/unstable-book/src/relaxed-adts.md new file mode 100644 index 0000000000000..170570e06a2ed --- /dev/null +++ b/src/doc/unstable-book/src/relaxed-adts.md @@ -0,0 +1,10 @@ +# `relaxed_adts` + +The tracking issue for this feature is: [#35626] + +[#35626]: https://github.com/rust-lang/rust/issues/35626 + +------------------------ + + + diff --git a/src/doc/unstable-book/src/repr-simd.md b/src/doc/unstable-book/src/repr-simd.md new file mode 100644 index 0000000000000..c6f051e4fffc1 --- /dev/null +++ b/src/doc/unstable-book/src/repr-simd.md @@ -0,0 +1,10 @@ +# `repr_simd` + +The tracking issue for this feature is: [#27731] + +[#27731]: https://github.com/rust-lang/rust/issues/27731 + +------------------------ + + + diff --git a/src/doc/unstable-book/src/rustc-attrs.md b/src/doc/unstable-book/src/rustc-attrs.md new file mode 100644 index 0000000000000..d1f18cead0683 --- /dev/null +++ b/src/doc/unstable-book/src/rustc-attrs.md @@ -0,0 +1,10 @@ +# `rustc_attrs` + +The tracking issue for this feature is: [#29642] + +[#29642]: https://github.com/rust-lang/rust/issues/29642 + +------------------------ + + + diff --git a/src/doc/unstable-book/src/rustc-diagnostic-macros.md b/src/doc/unstable-book/src/rustc-diagnostic-macros.md new file mode 100644 index 0000000000000..0df6ca12089ee --- /dev/null +++ b/src/doc/unstable-book/src/rustc-diagnostic-macros.md @@ -0,0 +1,6 @@ +# `rustc_diagnostic_macros` + +The tracking issue for this feature is: None. + +------------------------ + diff --git a/src/doc/unstable-book/src/sanitizer-runtime.md b/src/doc/unstable-book/src/sanitizer-runtime.md new file mode 100644 index 0000000000000..f19504de58e12 --- /dev/null +++ b/src/doc/unstable-book/src/sanitizer-runtime.md @@ -0,0 +1,6 @@ +# `sanitizer_runtime` + +The tracking issue for this feature is: None. + +------------------------ + diff --git a/src/doc/unstable-book/src/simd-ffi.md b/src/doc/unstable-book/src/simd-ffi.md new file mode 100644 index 0000000000000..d85779c3d3dc9 --- /dev/null +++ b/src/doc/unstable-book/src/simd-ffi.md @@ -0,0 +1,10 @@ +# `simd_ffi` + +The tracking issue for this feature is: [#27731] + +[#27731]: https://github.com/rust-lang/rust/issues/27731 + +------------------------ + + + diff --git a/src/doc/unstable-book/src/simd.md b/src/doc/unstable-book/src/simd.md new file mode 100644 index 0000000000000..13c9722c5243a --- /dev/null +++ b/src/doc/unstable-book/src/simd.md @@ -0,0 +1,10 @@ +# `simd` + +The tracking issue for this feature is: [#27731] + +[#27731]: https://github.com/rust-lang/rust/issues/27731 + +------------------------ + + + diff --git a/src/doc/unstable-book/src/slice-patterns.md b/src/doc/unstable-book/src/slice-patterns.md new file mode 100644 index 0000000000000..1e9e1eaafda46 --- /dev/null +++ b/src/doc/unstable-book/src/slice-patterns.md @@ -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), + _ => {}, + } +} +``` + diff --git a/src/doc/unstable-book/src/specialization.md b/src/doc/unstable-book/src/specialization.md new file mode 100644 index 0000000000000..59f27343b66df --- /dev/null +++ b/src/doc/unstable-book/src/specialization.md @@ -0,0 +1,8 @@ +# `specialization` + +The tracking issue for this feature is: [#31844] + +------------------------ + + + diff --git a/src/doc/unstable-book/src/staged-api.md b/src/doc/unstable-book/src/staged-api.md new file mode 100644 index 0000000000000..1409e570e887b --- /dev/null +++ b/src/doc/unstable-book/src/staged-api.md @@ -0,0 +1,6 @@ +# `staged_api` + +The tracking issue for this feature is: None. + +------------------------ + diff --git a/src/doc/unstable-book/src/start.md b/src/doc/unstable-book/src/start.md new file mode 100644 index 0000000000000..1ea6d59c78d5b --- /dev/null +++ b/src/doc/unstable-book/src/start.md @@ -0,0 +1,10 @@ +# `start` + +The tracking issue for this feature is: [#29633] + +[#29633]: https://github.com/rust-lang/rust/issues/29633 + +------------------------ + + + diff --git a/src/doc/unstable-book/src/static-nobundle.md b/src/doc/unstable-book/src/static-nobundle.md new file mode 100644 index 0000000000000..97b9d71d433a4 --- /dev/null +++ b/src/doc/unstable-book/src/static-nobundle.md @@ -0,0 +1,10 @@ +# `static_nobundle` + +The tracking issue for this feature is: [#37403] + +[#37403]: https://github.com/rust-lang/rust/issues/37403 + +------------------------ + + + diff --git a/src/doc/unstable-book/src/static-recursion.md b/src/doc/unstable-book/src/static-recursion.md new file mode 100644 index 0000000000000..d419ea41c6ffb --- /dev/null +++ b/src/doc/unstable-book/src/static-recursion.md @@ -0,0 +1,10 @@ +# `static_recursion` + +The tracking issue for this feature is: [#29719] + +[#29719]: https://github.com/rust-lang/rust/issues/29719 + +------------------------ + + + diff --git a/src/doc/unstable-book/src/stmt-expr-attributes.md b/src/doc/unstable-book/src/stmt-expr-attributes.md new file mode 100644 index 0000000000000..71092fcf29040 --- /dev/null +++ b/src/doc/unstable-book/src/stmt-expr-attributes.md @@ -0,0 +1,10 @@ +# `stmt_expr_attributes` + +The tracking issue for this feature is: [#15701] + +[#15701]: https://github.com/rust-lang/rust/issues/15701 + +------------------------ + + + diff --git a/src/doc/unstable-book/src/struct-field-attributes.md b/src/doc/unstable-book/src/struct-field-attributes.md new file mode 100644 index 0000000000000..1a94562968d19 --- /dev/null +++ b/src/doc/unstable-book/src/struct-field-attributes.md @@ -0,0 +1,10 @@ +# `struct_field_attributes` + +The tracking issue for this feature is: [#38814] + +[#38814]: https://github.com/rust-lang/rust/issues/38814 + +------------------------ + + + diff --git a/src/doc/unstable-book/src/structural-match.md b/src/doc/unstable-book/src/structural-match.md new file mode 100644 index 0000000000000..b3ca26e6474de --- /dev/null +++ b/src/doc/unstable-book/src/structural-match.md @@ -0,0 +1,10 @@ +# `structural_match` + +The tracking issue for this feature is: [#31434] + +[#31434]: https://github.com/rust-lang/rust/issues/31434 + +------------------------ + + + diff --git a/src/doc/unstable-book/src/target-feature.md b/src/doc/unstable-book/src/target-feature.md new file mode 100644 index 0000000000000..85ab1ab39efe6 --- /dev/null +++ b/src/doc/unstable-book/src/target-feature.md @@ -0,0 +1,6 @@ +# `target_feature` + +The tracking issue for this feature is: None. + +------------------------ + diff --git a/src/doc/book/src/benchmark-tests.md b/src/doc/unstable-book/src/test.md similarity index 92% rename from src/doc/book/src/benchmark-tests.md rename to src/doc/unstable-book/src/test.md index a6ae2b3049a3b..6b4a3a677db61 100644 --- a/src/doc/book/src/benchmark-tests.md +++ b/src/doc/unstable-book/src/test.md @@ -1,7 +1,13 @@ -# Benchmark tests +# `test` -Rust supports benchmark tests, which can test the performance of your -code. Let's make our `src/lib.rs` look like this (comments elided): +The tracking issue for this feature is: None. + +------------------------ + +The internals of the `test` crate are unstable, behind the `test` flag. The +most widely used part of the `test` crate are benchmark tests, which can test +the performance of your code. Let's make our `src/lib.rs` look like this +(comments elided): ```rust,ignore #![feature(test)] diff --git a/src/doc/unstable-book/src/the-unstable-book.md b/src/doc/unstable-book/src/the-unstable-book.md new file mode 100644 index 0000000000000..dfbfe4cab9738 --- /dev/null +++ b/src/doc/unstable-book/src/the-unstable-book.md @@ -0,0 +1,22 @@ +# The Unstable Book + +Welcome to the Unstable Book! This book consists of a number of chapters, +each one organized by a "feature flag." That is, when using an unstable +feature of Rust, you must use a flag, like this: + +```rust +#![feature(box_syntax)] + +fn main() { + let five = box 5; +} +``` + +The `box_syntax` feature [has a chapter][box] describing how to use it. + +[box]: box-syntax.html + +Because this documentation relates to unstable features, we make no guarantees +that what is contained here is accurate or up to date. It's developed on a +best-effort basis. Each page will have a link to its tracking issue with the +latest developments; you might want to check those as well. diff --git a/src/doc/unstable-book/src/thread-local.md b/src/doc/unstable-book/src/thread-local.md new file mode 100644 index 0000000000000..83de2f9cd4b54 --- /dev/null +++ b/src/doc/unstable-book/src/thread-local.md @@ -0,0 +1,10 @@ +# `thread_local` + +The tracking issue for this feature is: [#29594] + +[#29594]: https://github.com/rust-lang/rust/issues/29594 + +------------------------ + + + diff --git a/src/doc/unstable-book/src/trace-macros.md b/src/doc/unstable-book/src/trace-macros.md new file mode 100644 index 0000000000000..856f1b0a7bbb0 --- /dev/null +++ b/src/doc/unstable-book/src/trace-macros.md @@ -0,0 +1,10 @@ +# `trace_macros` + +The tracking issue for this feature is: [#29598] + +[#29598]: https://github.com/rust-lang/rust/issues/29598 + +------------------------ + + + diff --git a/src/doc/unstable-book/src/type-ascription.md b/src/doc/unstable-book/src/type-ascription.md new file mode 100644 index 0000000000000..3ebd0d87ccff9 --- /dev/null +++ b/src/doc/unstable-book/src/type-ascription.md @@ -0,0 +1,10 @@ +# `type_ascription` + +The tracking issue for this feature is: [#23416] + +[#23416]: https://github.com/rust-lang/rust/issues/23416 + +------------------------ + + + diff --git a/src/doc/unstable-book/src/unboxed-closures.md b/src/doc/unstable-book/src/unboxed-closures.md new file mode 100644 index 0000000000000..2cbb436ce0bb1 --- /dev/null +++ b/src/doc/unstable-book/src/unboxed-closures.md @@ -0,0 +1,10 @@ +# `unboxed_closures` + +The tracking issue for this feature is: [#29625] + +[#29625]: https://github.com/rust-lang/rust/issues/29625 + +------------------------ + + + diff --git a/src/doc/unstable-book/src/untagged-unions.md b/src/doc/unstable-book/src/untagged-unions.md new file mode 100644 index 0000000000000..6fe4f088ac237 --- /dev/null +++ b/src/doc/unstable-book/src/untagged-unions.md @@ -0,0 +1,10 @@ +# `untagged_unions` + +The tracking issue for this feature is: [#32836] + +[#32836]: https://github.com/rust-lang/rust/issues/32836 + +------------------------ + + + diff --git a/src/doc/unstable-book/src/unwind-attributes.md b/src/doc/unstable-book/src/unwind-attributes.md new file mode 100644 index 0000000000000..0167a33b081a5 --- /dev/null +++ b/src/doc/unstable-book/src/unwind-attributes.md @@ -0,0 +1,6 @@ +# `unwind_attributes` + +The tracking issue for this feature is: None. + +------------------------ + diff --git a/src/doc/unstable-book/src/use-extern-macros.md b/src/doc/unstable-book/src/use-extern-macros.md new file mode 100644 index 0000000000000..bc6149115028f --- /dev/null +++ b/src/doc/unstable-book/src/use-extern-macros.md @@ -0,0 +1,10 @@ +# `use_extern_macros` + +The tracking issue for this feature is: [#35896] + +[#35896]: https://github.com/rust-lang/rust/issues/35896 + +------------------------ + + + diff --git a/src/doc/unstable-book/src/windows-subsystem.md b/src/doc/unstable-book/src/windows-subsystem.md new file mode 100644 index 0000000000000..80583352fbf96 --- /dev/null +++ b/src/doc/unstable-book/src/windows-subsystem.md @@ -0,0 +1,10 @@ +# `windows_subsystem` + +The tracking issue for this feature is: [#37499] + +[#37499]: https://github.com/rust-lang/rust/issues/37499 + +------------------------ + + + diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 1bed3e2784773..b7be084fa0bab 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -91,11 +91,14 @@ macro_rules! declare_features { } } -// If you change this list without updating src/doc/reference.md, @cmr will be sad +// If you change this, please modify src/doc/unstable-book as well. +// // Don't ever remove anything from this list; set them to 'Removed'. +// // The version numbers here correspond to the version in which the current status // was set. This is most important for knowing when a particular feature became // stable (active). +// // NB: The featureck.py script parses this information directly out of the source // so take care when modifying it. @@ -385,7 +388,9 @@ declare_features! ( // Allows field shorthands (`x` meaning `x: x`) in struct literal expressions. (accepted, field_init_shorthand, "1.17.0", Some(37340)), ); -// (changing above list without updating src/doc/reference.md makes @cmr sad) +// If you change this, please modify src/doc/unstable-book as well. You must +// move that documentation into the relevant place in the other docs, and +// remove the chapter on the flag. #[derive(PartialEq, Copy, Clone, Debug)] pub enum AttributeType {