diff --git a/src/doc/trpl/README.md b/src/doc/trpl/README.md
index eb9e2b24ac9..f5dd92f5a3d 100644
--- a/src/doc/trpl/README.md
+++ b/src/doc/trpl/README.md
@@ -29,7 +29,12 @@ and will be able to understand most Rust code and write more complex programs.
In a similar fashion to "Intermediate," this section is full of individual,
deep-dive chapters, which stand alone and can be read in any order. These
-chapters focus on the most complex features, as well as some things that
-are only available in upcoming versions of Rust.
+chapters focus on the most complex features,
-After reading "Advanced," you'll be a Rust expert!
+
+
+In a similar fashion to "Intermediate," this section is full of individual,
+deep-dive chapters, which stand alone and can be read in any order.
+
+This chapter contains things that are only available on the nightly channel of
+Rust.
diff --git a/src/doc/trpl/SUMMARY.md b/src/doc/trpl/SUMMARY.md
index 70c74825a07..140086e32d0 100644
--- a/src/doc/trpl/SUMMARY.md
+++ b/src/doc/trpl/SUMMARY.md
@@ -36,6 +36,12 @@
* [FFI](ffi.md)
* [Unsafe Code](unsafe.md)
* [Advanced Macros](advanced-macros.md)
+* [Unstable Rust](unstable.md)
* [Compiler Plugins](plugins.md)
+ * [Inline Assembly](inline-assembly.md)
+ * [No stdlib](no-stdlib.md)
+ * [Intrinsics](intrinsics.md)
+ * [Lang items](lang-items.md)
+ * [Link args](link-args.md)
* [Conclusion](conclusion.md)
* [Glossary](glossary.md)
diff --git a/src/doc/trpl/advanced-macros.md b/src/doc/trpl/advanced-macros.md
index 86279f7f1a1..fef458caaaf 100644
--- a/src/doc/trpl/advanced-macros.md
+++ b/src/doc/trpl/advanced-macros.md
@@ -206,8 +206,6 @@ the [Bitwise Cyclic Tag](http://esolangs.org/wiki/Bitwise_Cyclic_Tag) automaton
within Rust's macro system.
```rust
-#![feature(trace_macros)]
-
macro_rules! bct {
// cmd 0: d ... => ...
(0, $($ps:tt),* ; $_d:tt)
@@ -229,13 +227,6 @@ macro_rules! bct {
( $($ps:tt),* ; )
=> (());
}
-
-fn main() {
- trace_macros!(true);
-# /* just check the definition
- bct!(0, 0, 1, 1, 1 ; 1, 0, 1);
-# */
-}
```
Exercise: use macros to reduce duplication in the above definition of the
diff --git a/src/doc/trpl/ffi.md b/src/doc/trpl/ffi.md
index 695279e2d5b..3dff72b3794 100644
--- a/src/doc/trpl/ffi.md
+++ b/src/doc/trpl/ffi.md
@@ -366,31 +366,6 @@ A few examples of how this model can be used are:
On OSX, frameworks behave with the same semantics as a dynamic library.
-## The `link_args` attribute
-
-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:
-
-``` 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, 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.
-
-It is highly recommended to *not* use this attribute, and rather use the more
-formal `#[link(...)]` attribute on `extern` blocks instead.
-
# Unsafe blocks
Some operations, like dereferencing unsafe pointers or calling functions that have been marked
diff --git a/src/doc/trpl/inline-assembly.md b/src/doc/trpl/inline-assembly.md
new file mode 100644
index 00000000000..1a4592f980f
--- /dev/null
+++ b/src/doc/trpl/inline-assembly.md
@@ -0,0 +1,141 @@
+% Inline Assembly
+
+For extremely low-level manipulations and performance reasons, one
+might wish to control the CPU directly. Rust supports using inline
+assembly to do this via the `asm!` macro. The syntax roughly matches
+that of GCC & Clang:
+
+```ignore
+asm!(assembly template
+ : output operands
+ : input operands
+ : clobbers
+ : options
+ );
+```
+
+Any use of `asm` is feature gated (requires `#![feature(asm)]` on the
+crate to allow) and of course requires an `unsafe` block.
+
+> **Note**: the examples here are given in x86/x86-64 assembly, but
+> all platforms are supported.
+
+## Assembly template
+
+The `assembly template` is the only required parameter and must be a
+literal string (i.e. `""`)
+
+```
+#![feature(asm)]
+
+#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+fn foo() {
+ unsafe {
+ asm!("NOP");
+ }
+}
+
+// other platforms
+#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
+fn foo() { /* ... */ }
+
+fn main() {
+ // ...
+ foo();
+ // ...
+}
+```
+
+(The `feature(asm)` and `#[cfg]`s are omitted from now on.)
+
+Output operands, input operands, clobbers and options are all optional
+but you must add the right number of `:` if you skip them:
+
+```
+# #![feature(asm)]
+# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+# fn main() { unsafe {
+asm!("xor %eax, %eax"
+ :
+ :
+ : "eax"
+ );
+# } }
+```
+
+Whitespace also doesn't matter:
+
+```
+# #![feature(asm)]
+# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+# fn main() { unsafe {
+asm!("xor %eax, %eax" ::: "eax");
+# } }
+```
+
+## Operands
+
+Input and output operands follow the same format: `:
+"constraints1"(expr1), "constraints2"(expr2), ..."`. Output operand
+expressions must be mutable lvalues:
+
+```
+# #![feature(asm)]
+# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+fn add(a: i32, b: i32) -> i32 {
+ let mut c = 0;
+ unsafe {
+ asm!("add $2, $0"
+ : "=r"(c)
+ : "0"(a), "r"(b)
+ );
+ }
+ c
+}
+# #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
+# fn add(a: i32, b: i32) -> i32 { a + b }
+
+fn main() {
+ assert_eq!(add(3, 14159), 14162)
+}
+```
+
+## Clobbers
+
+Some instructions modify registers which might otherwise have held
+different values so we use the clobbers list to indicate to the
+compiler not to assume any values loaded into those registers will
+stay valid.
+
+```
+# #![feature(asm)]
+# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+# fn main() { unsafe {
+// Put the value 0x200 in eax
+asm!("mov $$0x200, %eax" : /* no outputs */ : /* no inputs */ : "eax");
+# } }
+```
+
+Input and output registers need not be listed since that information
+is already communicated by the given constraints. Otherwise, any other
+registers used either implicitly or explicitly should be listed.
+
+If the assembly changes the condition code register `cc` should be
+specified as one of the clobbers. Similarly, if the assembly modifies
+memory, `memory` should also be specified.
+
+## Options
+
+The last section, `options` is specific to Rust. The format is comma
+separated literal strings (i.e. `:"foo", "bar", "baz"`). It's used to
+specify some extra info about the inline assembly:
+
+Current valid options are:
+
+1. *volatile* - specifying this is analogous to
+ `__asm__ __volatile__ (...)` in gcc/clang.
+2. *alignstack* - certain instructions expect the stack to be
+ aligned a certain way (i.e. SSE) and specifying this indicates to
+ the compiler to insert its usual stack alignment code
+3. *intel* - use intel syntax instead of the default AT&T.
+
diff --git a/src/doc/trpl/intrinsics.md b/src/doc/trpl/intrinsics.md
new file mode 100644
index 00000000000..25f7c544931
--- /dev/null
+++ b/src/doc/trpl/intrinsics.md
@@ -0,0 +1,25 @@
+% Intrinsics
+
+> **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
+context, but wished to be able to `transmute` between types, and
+perform efficient pointer arithmetic, one would import those functions
+via a declaration like
+
+```
+# #![feature(intrinsics)]
+# fn main() {}
+
+extern "rust-intrinsic" {
+ fn transmute(x: T) -> U;
+
+ fn offset(dst: *const T, offset: isize) -> *const T;
+}
+```
+
+As with any other FFI functions, these are always `unsafe` to call.
+
diff --git a/src/doc/trpl/lang-items.md b/src/doc/trpl/lang-items.md
new file mode 100644
index 00000000000..30ab59cc029
--- /dev/null
+++ b/src/doc/trpl/lang-items.md
@@ -0,0 +1,79 @@
+% 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`:
+
+```
+#![feature(lang_items, box_syntax, start, no_std)]
+#![no_std]
+
+extern crate libc;
+
+extern {
+ fn abort() -> !;
+}
+
+#[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;
+
+ // malloc failed
+ if p as usize == 0 {
+ abort();
+ }
+
+ p
+}
+#[lang="exchange_free"]
+unsafe fn deallocate(ptr: *mut u8, _size: usize, _align: usize) {
+ libc::free(ptr as *mut libc::c_void)
+}
+
+#[start]
+fn main(argc: isize, argv: *const *const u8) -> isize {
+ let x = box 1;
+
+ 0
+}
+
+#[lang = "stack_exhausted"] extern fn stack_exhausted() {}
+#[lang = "eh_personality"] extern fn eh_personality() {}
+#[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} }
+```
+
+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`, `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/trpl/link-args.md b/src/doc/trpl/link-args.md
new file mode 100644
index 00000000000..ee5159afb8e
--- /dev/null
+++ b/src/doc/trpl/link-args.md
@@ -0,0 +1,25 @@
+% 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:
+
+``` 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, 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.
+
+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/trpl/no-stdlib.md b/src/doc/trpl/no-stdlib.md
new file mode 100644
index 00000000000..539a0729ba3
--- /dev/null
+++ b/src/doc/trpl/no-stdlib.md
@@ -0,0 +1,168 @@
+% No stdlib
+
+By default, `std` is linked to every Rust crate. In some contexts,
+this is undesirable, and can be avoided with the `#![no_std]`
+attribute attached to the crate.
+
+```ignore
+// a minimal library
+#![crate_type="lib"]
+#![feature(no_std)]
+#![no_std]
+# // fn main() {} tricked you, rustdoc!
+```
+
+Obviously there's more to life than just libraries: one can use
+`#[no_std]` with an executable, controlling the entry point is
+possible in two ways: the `#[start]` attribute, or overriding the
+default shim for the C `main` function with your own.
+
+The function marked `#[start]` is passed the command line parameters
+in the same format as C:
+
+```
+#![feature(lang_items, start, no_std)]
+#![no_std]
+
+// Pull in the system libc library for what crt0.o likely requires
+extern crate libc;
+
+// Entry point for this program
+#[start]
+fn start(_argc: isize, _argv: *const *const u8) -> isize {
+ 0
+}
+
+// These functions and traits are used by the compiler, but not
+// for a bare-bones hello world. These are normally
+// provided by libstd.
+#[lang = "stack_exhausted"] extern fn stack_exhausted() {}
+#[lang = "eh_personality"] extern fn eh_personality() {}
+#[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} }
+# // fn main() {} tricked you, rustdoc!
+```
+
+To override the compiler-inserted `main` shim, one has to disable it
+with `#![no_main]` and then create the appropriate symbol with the
+correct ABI and the correct name, which requires overriding the
+compiler's name mangling too:
+
+```ignore
+#![feature(no_std)]
+#![no_std]
+#![no_main]
+#![feature(lang_items, start)]
+
+extern crate libc;
+
+#[no_mangle] // ensure that this symbol is called `main` in the output
+pub extern fn main(argc: i32, argv: *const *const u8) -> i32 {
+ 0
+}
+
+#[lang = "stack_exhausted"] extern fn stack_exhausted() {}
+#[lang = "eh_personality"] extern fn eh_personality() {}
+#[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} }
+# // fn main() {} tricked you, rustdoc!
+```
+
+
+The compiler currently makes a few assumptions about symbols which are available
+in the executable to call. Normally these functions are provided by the standard
+library, but without it you must define your own.
+
+The first of these three functions, `stack_exhausted`, is invoked whenever stack
+overflow is detected. This function has a number of restrictions about how it
+can be called and what it must do, but if the stack limit register is not being
+maintained then a thread always has an "infinite stack" and this function
+shouldn't get triggered.
+
+The second of these three functions, `eh_personality`, is used by the
+failure mechanisms of the compiler. This is often mapped to GCC's
+personality function (see the
+[libstd implementation](../std/rt/unwind/index.html) for more
+information), but crates which do not trigger a panic can be assured
+that this function is never called. The final function, `panic_fmt`, is
+also used by the failure mechanisms of the compiler.
+
+## Using libcore
+
+> **Note**: the core library's structure is unstable, and it is recommended to
+> use the standard library instead wherever possible.
+
+With the above techniques, we've got a bare-metal executable running some Rust
+code. There is a good deal of functionality provided by the standard library,
+however, that is necessary to be productive in Rust. If the standard library is
+not sufficient, then [libcore](../core/index.html) is designed to be used
+instead.
+
+The core library has very few dependencies and is much more portable than the
+standard library itself. Additionally, the core library has most of the
+necessary functionality for writing idiomatic and effective Rust code.
+
+As an example, here is a program that will calculate the dot product of two
+vectors provided from C, using idiomatic Rust practices.
+
+```
+#![feature(lang_items, start, no_std)]
+#![no_std]
+
+# extern crate libc;
+extern crate core;
+
+use core::prelude::*;
+
+use core::mem;
+
+#[no_mangle]
+pub extern fn dot_product(a: *const u32, a_len: u32,
+ b: *const u32, b_len: u32) -> u32 {
+ use core::raw::Slice;
+
+ // Convert the provided arrays into Rust slices.
+ // The core::raw module guarantees that the Slice
+ // structure has the same memory layout as a &[T]
+ // slice.
+ //
+ // This is an unsafe operation because the compiler
+ // cannot tell the pointers are valid.
+ let (a_slice, b_slice): (&[u32], &[u32]) = unsafe {
+ mem::transmute((
+ Slice { data: a, len: a_len as usize },
+ Slice { data: b, len: b_len as usize },
+ ))
+ };
+
+ // Iterate over the slices, collecting the result
+ let mut ret = 0;
+ for (i, j) in a_slice.iter().zip(b_slice.iter()) {
+ ret += (*i) * (*j);
+ }
+ return ret;
+}
+
+#[lang = "panic_fmt"]
+extern fn panic_fmt(args: &core::fmt::Arguments,
+ file: &str,
+ line: u32) -> ! {
+ loop {}
+}
+
+#[lang = "stack_exhausted"] extern fn stack_exhausted() {}
+#[lang = "eh_personality"] extern fn eh_personality() {}
+# #[start] fn start(argc: isize, argv: *const *const u8) -> isize { 0 }
+# fn main() {}
+```
+
+Note that there is one extra lang item here which differs from the examples
+above, `panic_fmt`. This must be defined by consumers of libcore because the
+core library declares panics, but it does not define it. The `panic_fmt`
+lang item is this crate's definition of panic, and it must be guaranteed to
+never return.
+
+As can be seen in this example, the core library is intended to provide the
+power of Rust in all circumstances, regardless of platform requirements. Further
+libraries, such as liballoc, add functionality to libcore which make other
+platform-specific assumptions, but continue to be more portable than the
+standard library itself.
+
diff --git a/src/doc/trpl/plugins.md b/src/doc/trpl/plugins.md
index 33f0893466d..9eb22a7f698 100644
--- a/src/doc/trpl/plugins.md
+++ b/src/doc/trpl/plugins.md
@@ -1,29 +1,5 @@
% Compiler Plugins
-
-
-
-Warning: Plugins are an advanced, unstable feature! For many details,
-the only available documentation is the libsyntax
and librustc
API docs, or even the source
-code itself. These internal compiler APIs are also subject to change at any
-time.
-
-
-
-For defining new syntax it is often much easier to use Rust's built-in macro system.
-
-
-
-The code in this document uses language features not covered in the Rust
-Guide. See the Reference Manual for more
-information.
-
-
-
-
# Introduction
`rustc` can load compiler plugins, which are user-provided libraries that
diff --git a/src/doc/trpl/tracing-macros.md b/src/doc/trpl/tracing-macros.md
new file mode 100644
index 00000000000..bc337f30515
--- /dev/null
+++ b/src/doc/trpl/tracing-macros.md
@@ -0,0 +1,90 @@
+% Tracing Macros
+
+The `trace_macros` feature allows you to use a special feature: tracing macro
+invocations.
+
+In the advanced macros chapter, we defined a `bct` macro:
+
+```rust
+macro_rules! bct {
+ // cmd 0: d ... => ...
+ (0, $($ps:tt),* ; $_d:tt)
+ => (bct!($($ps),*, 0 ; ));
+ (0, $($ps:tt),* ; $_d:tt, $($ds:tt),*)
+ => (bct!($($ps),*, 0 ; $($ds),*));
+
+ // cmd 1p: 1 ... => 1 ... p
+ (1, $p:tt, $($ps:tt),* ; 1)
+ => (bct!($($ps),*, 1, $p ; 1, $p));
+ (1, $p:tt, $($ps:tt),* ; 1, $($ds:tt),*)
+ => (bct!($($ps),*, 1, $p ; 1, $($ds),*, $p));
+
+ // cmd 1p: 0 ... => 0 ...
+ (1, $p:tt, $($ps:tt),* ; $($ds:tt),*)
+ => (bct!($($ps),*, 1, $p ; $($ds),*));
+
+ // halt on empty data string
+ ( $($ps:tt),* ; )
+ => (());
+}
+```
+
+This is pretty complex! we can see the output
+
+ ```rust
+#![feature(trace_macros)]
+
+macro_rules! bct {
+ // cmd 0: d ... => ...
+ (0, $($ps:tt),* ; $_d:tt)
+ => (bct!($($ps),*, 0 ; ));
+ (0, $($ps:tt),* ; $_d:tt, $($ds:tt),*)
+ => (bct!($($ps),*, 0 ; $($ds),*));
+
+ // cmd 1p: 1 ... => 1 ... p
+ (1, $p:tt, $($ps:tt),* ; 1)
+ => (bct!($($ps),*, 1, $p ; 1, $p));
+ (1, $p:tt, $($ps:tt),* ; 1, $($ds:tt),*)
+ => (bct!($($ps),*, 1, $p ; 1, $($ds),*, $p));
+
+ // cmd 1p: 0 ... => 0 ...
+ (1, $p:tt, $($ps:tt),* ; $($ds:tt),*)
+ => (bct!($($ps),*, 1, $p ; $($ds),*));
+
+ // halt on empty data string
+ ( $($ps:tt),* ; )
+ => (());
+}
+
+fn main() {
+ trace_macros!(true);
+
+ bct!(0, 0, 1, 1, 1 ; 1, 0, 1);
+}
+
+This will print out a wall of text:
+
+```text
+bct! { 0 , 0 , 1 , 1 , 1 ; 1 , 0 , 1 }
+bct! { 0 , 1 , 1 , 1 , 0 ; 0 , 1 }
+bct! { 1 , 1 , 1 , 0 , 0 ; 1 }
+bct! { 1 , 0 , 0 , 1 , 1 ; 1 , 1 }
+bct! { 0 , 1 , 1 , 1 , 0 ; 1 , 1 , 0 }
+bct! { 1 , 1 , 1 , 0 , 0 ; 1 , 0 }
+bct! { 1 , 0 , 0 , 1 , 1 ; 1 , 0 , 1 }
+bct! { 0 , 1 , 1 , 1 , 0 ; 1 , 0 , 1 , 0 }
+bct! { 1 , 1 , 1 , 0 , 0 ; 0 , 1 , 0 }
+bct! { 1 , 0 , 0 , 1 , 1 ; 0 , 1 , 0 }
+bct! { 0 , 1 , 1 , 1 , 0 ; 0 , 1 , 0 }
+```
+
+And eventually, error:
+
+```text
+18:45 error: recursion limit reached while expanding the macro `bct`
+ => (bct!($($ps),*, 1, $p ; $($ds),*));
+ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+```
+
+The `trace_macros!` call is what produces this output, showing how we match
+each time.
diff --git a/src/doc/trpl/unsafe.md b/src/doc/trpl/unsafe.md
index dbf0cae6f4b..3ca3cfd0588 100644
--- a/src/doc/trpl/unsafe.md
+++ b/src/doc/trpl/unsafe.md
@@ -181,539 +181,3 @@ code:
that clean-up is always run, even when the thread panics.
- ensure that any data stored behind a raw pointer is destroyed at the
appropriate time.
-
-As an example, we give a reimplementation of owned boxes by wrapping
-`malloc` and `free`. Rust's move semantics and lifetimes mean this
-reimplementation is as safe as the `Box` type.
-
-```
-# #![feature(libc)]
-#![feature(unsafe_destructor)]
-
-extern crate libc;
-use libc::{c_void, size_t, malloc, free};
-use std::mem;
-use std::ptr;
-
-// Define a wrapper around the handle returned by the foreign code.
-// Unique has the same semantics as Box
-//
-// NB: For simplicity and correctness, we require that T has kind Send
-// (owned boxes relax this restriction).
-pub struct Unique {
- // It contains a single raw, mutable pointer to the object in question.
- ptr: *mut T
-}
-
-// Implement methods for creating and using the values in the box.
-
-impl Unique {
- pub fn new(value: T) -> Unique {
- unsafe {
- let ptr = malloc(mem::size_of::() as size_t) as *mut T;
- // we *need* valid pointer.
- assert!(!ptr.is_null());
- // `*ptr` is uninitialized, and `*ptr = value` would
- // attempt to destroy it `overwrite` moves a value into
- // this memory without attempting to drop the original
- // value.
- ptr::write(&mut *ptr, value);
- Unique{ptr: ptr}
- }
- }
-
- // the 'r lifetime results in the same semantics as `&*x` with
- // Box
- pub fn borrow<'r>(&'r self) -> &'r T {
- // By construction, self.ptr is valid
- unsafe { &*self.ptr }
- }
-
- // the 'r lifetime results in the same semantics as `&mut *x` with
- // Box
- pub fn borrow_mut<'r>(&'r mut self) -> &'r mut T {
- unsafe { &mut *self.ptr }
- }
-}
-
-// A key ingredient for safety, we associate a destructor with
-// Unique, making the struct manage the raw pointer: when the
-// struct goes out of scope, it will automatically free the raw pointer.
-//
-// NB: This is an unsafe destructor; rustc will not normally allow
-// destructors to be associated with parameterized types (due to
-// historically failing to check them soundly). Note that the
-// `#[unsafe_destructor]` feature gate is currently required to use
-// unsafe destructors.
-#[unsafe_destructor]
-impl Drop for Unique {
- fn drop(&mut self) {
- unsafe {
- // Copy the object out from the pointer onto the stack,
- // where it is covered by normal Rust destructor semantics
- // and cleans itself up, if necessary
- ptr::read(self.ptr);
-
- // clean-up our allocation
- free(self.ptr as *mut c_void)
- }
- }
-}
-
-// A comparison between the built-in `Box` and this reimplementation
-fn main() {
- {
- let mut x = Box::new(5);
- *x = 10;
- } // `x` is freed here
-
- {
- let mut y = Unique::new(5);
- *y.borrow_mut() = 10;
- } // `y` is freed here
-}
-```
-
-Notably, the only way to construct a `Unique` is via the `new`
-function, and this function ensures that the internal pointer is valid
-and hidden in the private field. The two `borrow` methods are safe
-because the compiler statically guarantees that objects are never used
-before creation or after destruction (unless you use some `unsafe`
-code...).
-
-# Inline assembly
-
-For extremely low-level manipulations and performance reasons, one
-might wish to control the CPU directly. Rust supports using inline
-assembly to do this via the `asm!` macro. The syntax roughly matches
-that of GCC & Clang:
-
-```ignore
-asm!(assembly template
- : output operands
- : input operands
- : clobbers
- : options
- );
-```
-
-Any use of `asm` is feature gated (requires `#![feature(asm)]` on the
-crate to allow) and of course requires an `unsafe` block.
-
-> **Note**: the examples here are given in x86/x86-64 assembly, but
-> all platforms are supported.
-
-## Assembly template
-
-The `assembly template` is the only required parameter and must be a
-literal string (i.e. `""`)
-
-```
-#![feature(asm)]
-
-#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
-fn foo() {
- unsafe {
- asm!("NOP");
- }
-}
-
-// other platforms
-#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
-fn foo() { /* ... */ }
-
-fn main() {
- // ...
- foo();
- // ...
-}
-```
-
-(The `feature(asm)` and `#[cfg]`s are omitted from now on.)
-
-Output operands, input operands, clobbers and options are all optional
-but you must add the right number of `:` if you skip them:
-
-```
-# #![feature(asm)]
-# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
-# fn main() { unsafe {
-asm!("xor %eax, %eax"
- :
- :
- : "eax"
- );
-# } }
-```
-
-Whitespace also doesn't matter:
-
-```
-# #![feature(asm)]
-# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
-# fn main() { unsafe {
-asm!("xor %eax, %eax" ::: "eax");
-# } }
-```
-
-## Operands
-
-Input and output operands follow the same format: `:
-"constraints1"(expr1), "constraints2"(expr2), ..."`. Output operand
-expressions must be mutable lvalues:
-
-```
-# #![feature(asm)]
-# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
-fn add(a: i32, b: i32) -> i32 {
- let mut c = 0;
- unsafe {
- asm!("add $2, $0"
- : "=r"(c)
- : "0"(a), "r"(b)
- );
- }
- c
-}
-# #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
-# fn add(a: i32, b: i32) -> i32 { a + b }
-
-fn main() {
- assert_eq!(add(3, 14159), 14162)
-}
-```
-
-## Clobbers
-
-Some instructions modify registers which might otherwise have held
-different values so we use the clobbers list to indicate to the
-compiler not to assume any values loaded into those registers will
-stay valid.
-
-```
-# #![feature(asm)]
-# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
-# fn main() { unsafe {
-// Put the value 0x200 in eax
-asm!("mov $$0x200, %eax" : /* no outputs */ : /* no inputs */ : "eax");
-# } }
-```
-
-Input and output registers need not be listed since that information
-is already communicated by the given constraints. Otherwise, any other
-registers used either implicitly or explicitly should be listed.
-
-If the assembly changes the condition code register `cc` should be
-specified as one of the clobbers. Similarly, if the assembly modifies
-memory, `memory` should also be specified.
-
-## Options
-
-The last section, `options` is specific to Rust. The format is comma
-separated literal strings (i.e. `:"foo", "bar", "baz"`). It's used to
-specify some extra info about the inline assembly:
-
-Current valid options are:
-
-1. *volatile* - specifying this is analogous to
- `__asm__ __volatile__ (...)` in gcc/clang.
-2. *alignstack* - certain instructions expect the stack to be
- aligned a certain way (i.e. SSE) and specifying this indicates to
- the compiler to insert its usual stack alignment code
-3. *intel* - use intel syntax instead of the default AT&T.
-
-# Avoiding the standard library
-
-By default, `std` is linked to every Rust crate. In some contexts,
-this is undesirable, and can be avoided with the `#![no_std]`
-attribute attached to the crate.
-
-```ignore
-// a minimal library
-#![crate_type="lib"]
-#![feature(no_std)]
-#![no_std]
-# // fn main() {} tricked you, rustdoc!
-```
-
-Obviously there's more to life than just libraries: one can use
-`#[no_std]` with an executable, controlling the entry point is
-possible in two ways: the `#[start]` attribute, or overriding the
-default shim for the C `main` function with your own.
-
-The function marked `#[start]` is passed the command line parameters
-in the same format as C:
-
-```
-# #![feature(libc)]
-#![feature(lang_items, start, no_std)]
-#![no_std]
-
-// Pull in the system libc library for what crt0.o likely requires
-extern crate libc;
-
-// Entry point for this program
-#[start]
-fn start(_argc: isize, _argv: *const *const u8) -> isize {
- 0
-}
-
-// These functions and traits are used by the compiler, but not
-// for a bare-bones hello world. These are normally
-// provided by libstd.
-#[lang = "stack_exhausted"] extern fn stack_exhausted() {}
-#[lang = "eh_personality"] extern fn eh_personality() {}
-#[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} }
-# // fn main() {} tricked you, rustdoc!
-```
-
-To override the compiler-inserted `main` shim, one has to disable it
-with `#![no_main]` and then create the appropriate symbol with the
-correct ABI and the correct name, which requires overriding the
-compiler's name mangling too:
-
-```ignore
-# #![feature(libc)]
-#![feature(no_std)]
-#![no_std]
-#![no_main]
-#![feature(lang_items, start)]
-
-extern crate libc;
-
-#[no_mangle] // ensure that this symbol is called `main` in the output
-pub extern fn main(argc: i32, argv: *const *const u8) -> i32 {
- 0
-}
-
-#[lang = "stack_exhausted"] extern fn stack_exhausted() {}
-#[lang = "eh_personality"] extern fn eh_personality() {}
-#[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} }
-# // fn main() {} tricked you, rustdoc!
-```
-
-
-The compiler currently makes a few assumptions about symbols which are available
-in the executable to call. Normally these functions are provided by the standard
-library, but without it you must define your own.
-
-The first of these three functions, `stack_exhausted`, is invoked whenever stack
-overflow is detected. This function has a number of restrictions about how it
-can be called and what it must do, but if the stack limit register is not being
-maintained then a thread always has an "infinite stack" and this function
-shouldn't get triggered.
-
-The second of these three functions, `eh_personality`, is used by the
-failure mechanisms of the compiler. This is often mapped to GCC's
-personality function (see the
-[libstd implementation](../std/rt/unwind/index.html) for more
-information), but crates which do not trigger a panic can be assured
-that this function is never called. The final function, `panic_fmt`, is
-also used by the failure mechanisms of the compiler.
-
-## Using libcore
-
-> **Note**: the core library's structure is unstable, and it is recommended to
-> use the standard library instead wherever possible.
-
-With the above techniques, we've got a bare-metal executable running some Rust
-code. There is a good deal of functionality provided by the standard library,
-however, that is necessary to be productive in Rust. If the standard library is
-not sufficient, then [libcore](../core/index.html) is designed to be used
-instead.
-
-The core library has very few dependencies and is much more portable than the
-standard library itself. Additionally, the core library has most of the
-necessary functionality for writing idiomatic and effective Rust code.
-
-As an example, here is a program that will calculate the dot product of two
-vectors provided from C, using idiomatic Rust practices.
-
-```
-# #![feature(libc, core)]
-#![feature(lang_items, start, no_std)]
-#![no_std]
-
-# extern crate libc;
-extern crate core;
-
-use core::prelude::*;
-
-use core::mem;
-
-#[no_mangle]
-pub extern fn dot_product(a: *const u32, a_len: u32,
- b: *const u32, b_len: u32) -> u32 {
- use core::raw::Slice;
-
- // Convert the provided arrays into Rust slices.
- // The core::raw module guarantees that the Slice
- // structure has the same memory layout as a &[T]
- // slice.
- //
- // This is an unsafe operation because the compiler
- // cannot tell the pointers are valid.
- let (a_slice, b_slice): (&[u32], &[u32]) = unsafe {
- mem::transmute((
- Slice { data: a, len: a_len as usize },
- Slice { data: b, len: b_len as usize },
- ))
- };
-
- // Iterate over the slices, collecting the result
- let mut ret = 0;
- for (i, j) in a_slice.iter().zip(b_slice.iter()) {
- ret += (*i) * (*j);
- }
- return ret;
-}
-
-#[lang = "panic_fmt"]
-extern fn panic_fmt(args: &core::fmt::Arguments,
- file: &str,
- line: u32) -> ! {
- loop {}
-}
-
-#[lang = "stack_exhausted"] extern fn stack_exhausted() {}
-#[lang = "eh_personality"] extern fn eh_personality() {}
-# #[start] fn start(argc: isize, argv: *const *const u8) -> isize { 0 }
-# fn main() {}
-```
-
-Note that there is one extra lang item here which differs from the examples
-above, `panic_fmt`. This must be defined by consumers of libcore because the
-core library declares panics, but it does not define it. The `panic_fmt`
-lang item is this crate's definition of panic, and it must be guaranteed to
-never return.
-
-As can be seen in this example, the core library is intended to provide the
-power of Rust in all circumstances, regardless of platform requirements. Further
-libraries, such as liballoc, add functionality to libcore which make other
-platform-specific assumptions, but continue to be more portable than the
-standard library itself.
-
-# Interacting with the compiler internals
-
-> **Note**: this section is specific to the `rustc` compiler; these
-> parts of the language may never be fully specified and so details may
-> differ wildly between implementations (and even versions of `rustc`
-> itself).
->
-> Furthermore, this is just an overview; the best form of
-> documentation for specific instances of these features are their
-> definitions and uses in `std`.
-
-The Rust language currently has two orthogonal mechanisms for allowing
-libraries to interact directly with the compiler and vice versa:
-
-- intrinsics, functions built directly into the compiler providing
- very basic low-level functionality,
-- lang-items, special functions, types and traits in libraries marked
- with specific `#[lang]` attributes
-
-## Intrinsics
-
-> **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
-context, but wished to be able to `transmute` between types, and
-perform efficient pointer arithmetic, one would import those functions
-via a declaration like
-
-```
-# #![feature(intrinsics)]
-# fn main() {}
-
-extern "rust-intrinsic" {
- fn transmute(x: T) -> U;
-
- fn offset(dst: *const T, offset: isize) -> *const T;
-}
-```
-
-As with any other FFI functions, these are always `unsafe` to call.
-
-## 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`:
-
-```
-# #![feature(libc)]
-#![feature(lang_items, box_syntax, start, no_std)]
-#![no_std]
-
-extern crate libc;
-
-extern {
- fn abort() -> !;
-}
-
-#[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;
-
- // malloc failed
- if p as usize == 0 {
- abort();
- }
-
- p
-}
-#[lang="exchange_free"]
-unsafe fn deallocate(ptr: *mut u8, _size: usize, _align: usize) {
- libc::free(ptr as *mut libc::c_void)
-}
-
-#[start]
-fn main(argc: isize, argv: *const *const u8) -> isize {
- let x = box 1;
-
- 0
-}
-
-#[lang = "stack_exhausted"] extern fn stack_exhausted() {}
-#[lang = "eh_personality"] extern fn eh_personality() {}
-#[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} }
-```
-
-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`, `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.