]> git.lizzy.rs Git - rust.git/blobdiff - src/doc/guide.md
auto merge of #18339 : chastell/rust/guide_pattern_fixes, r=nikomatsakis
[rust.git] / src / doc / guide.md
index 9b2c7adf92dd685ad0c81d1dd3cc9e6a14430140..f6aa04df1b9e0ad9108f57a4551d95f8f439a1bf 100644 (file)
@@ -1130,12 +1130,12 @@ fn main() {
     let y = Missing;
 
     match x {
-        Value(n) => println!("x is {:d}", n),
+        Value(n) => println!("x is {}", n),
         Missing  => println!("x is missing!"),
     }
 
     match y {
-        Value(n) => println!("y is {:d}", n),
+        Value(n) => println!("y is {}", n),
         Missing  => println!("y is missing!"),
     }
 }
@@ -1301,7 +1301,7 @@ Instead, it looks like this:
 
 ```{rust}
 for x in range(0i, 10i) {
-    println!("{:d}", x);
+    println!("{}", x);
 }
 ```
 
@@ -1408,7 +1408,7 @@ iteration: This will only print the odd numbers:
 for x in range(0i, 10i) {
     if x % 2 == 0 { continue; }
 
-    println!("{:d}", x);
+    println!("{}", x);
 }
 ```
 
@@ -1677,12 +1677,12 @@ fn main() {
     let y = Missing;
 
     match x {
-        Value(n) => println!("x is {:d}", n),
+        Value(n) => println!("x is {}", n),
         Missing  => println!("x is missing!"),
     }
 
     match y {
-        Value(n) => println!("y is {:d}", n),
+        Value(n) => println!("y is {}", n),
         Missing  => println!("y is missing!"),
     }
 }
@@ -1793,7 +1793,7 @@ Finally, Cargo generated a hello, world for us. Check out `src/main.rs`:
 
 ```{rust}
 fn main() {
-    println!("Hello, world!");
+    println!("Hello, world!")
 }
 ```
 
@@ -2682,12 +2682,12 @@ like this:
 
 ```
 fn main() {
-    println!("Hello, world!");
+    println!("Hello, world!")
 }
 
 mod hello {
     fn print_hello() {
-        println!("Hello, world!");
+        println!("Hello, world!")
     }
 }
 ```
@@ -2721,7 +2721,7 @@ fn main() {
 
 mod hello {
     fn print_hello() {
-        println!("Hello, world!");
+        println!("Hello, world!")
     }
 }
 ```
@@ -2744,7 +2744,7 @@ fn main() {
 
 mod hello {
     pub fn print_hello() {
-        println!("Hello, world!");
+        println!("Hello, world!")
     }
 }
 ```
@@ -2921,15 +2921,11 @@ it `false`, so this test should fail. Let's try it!
 ```{notrust,ignore}
 $ cargo test
    Compiling testing v0.0.1 (file:///home/you/projects/testing)
-/home/you/projects/testing/src/main.rs:1:1: 3:2 warning: code is never used: `main`, #[warn(dead_code)] on by default
+/home/you/projects/testing/src/main.rs:1:1: 3:2 warning: function is never used: `main`, #[warn(dead_code)] on by default
 /home/you/projects/testing/src/main.rs:1 fn main() {
-/home/you/projects/testing/src/main.rs:2     println!("Hello, world");
+/home/you/projects/testing/src/main.rs:2     println!("Hello, world!")
 /home/you/projects/testing/src/main.rs:3 }
-
-running 0 tests
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
-
+     Running target/lib-654ce120f310a3a5
 
 running 1 test
 test foo ... FAILED
@@ -2946,7 +2942,7 @@ failures:
 
 test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured
 
-task '<main>' failed at 'Some tests failed', /home/you/src/rust/src/libtest/lib.rs:242
+task '<main>' failed at 'Some tests failed', /home/you/src/rust/src/libtest/lib.rs:243
 ```
 
 Lots of output! Let's break this down:
@@ -2960,9 +2956,9 @@ You can run all of your tests with `cargo test`. This runs both your tests in
 `tests`, as well as the tests you put inside of your crate.
 
 ```{notrust,ignore}
-/home/you/projects/testing/src/main.rs:1:1: 3:2 warning: code is never used: `main`, #[warn(dead_code)] on by default
+/home/you/projects/testing/src/main.rs:1:1: 3:2 warning: function is never used: `main`, #[warn(dead_code)] on by default
 /home/you/projects/testing/src/main.rs:1 fn main() {
-/home/you/projects/testing/src/main.rs:2     println!("Hello, world");
+/home/you/projects/testing/src/main.rs:2     println!("Hello, world!")
 /home/you/projects/testing/src/main.rs:3 }
 ```
 
@@ -2974,18 +2970,8 @@ We'll turn this lint off for just this function soon. For now, just ignore this
 output.
 
 ```{notrust,ignore}
-running 0 tests
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
-```
+     Running target/lib-654ce120f310a3a5
 
-Wait a minute, zero tests? Didn't we define one? Yup. This output is from
-attempting to run the tests in our crate, of which we don't have any.
-You'll note that Rust reports on several kinds of tests: passed, failed,
-ignored, and measured. The 'measured' tests refer to benchmark tests, which
-we'll cover soon enough!
-
-```{notrust,ignore}
 running 1 test
 test foo ... FAILED
 ```
@@ -3008,7 +2994,7 @@ failures:
 
 test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured
 
-task '<main>' failed at 'Some tests failed', /home/you/src/rust/src/libtest/lib.rs:242
+task '<main>' failed at 'Some tests failed', /home/you/src/rust/src/libtest/lib.rs:243
 ```
 
 After all the tests run, Rust will show us any output from our failed tests.
@@ -3029,29 +3015,30 @@ And then try to run our tests again:
 ```{notrust,ignore}
 $ cargo test
    Compiling testing v0.0.1 (file:///home/you/projects/testing)
-/home/you/projects/testing/src/main.rs:1:1: 3:2 warning: code is never used: `main`, #[warn(dead_code)] on by default
-/home/you/projects/testing/src/main.rs:1 fn main() {
-/home/you/projects/testing/src/main.rs:2     println!("Hello, world");
-/home/you/projects/testing/src/main.rs:3 }
-
-running 0 tests
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
-
+     Running target/lib-654ce120f310a3a5
 
 running 1 test
 test foo ... ok
 
 test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+
+     Running target/testing-6d7518593c7c3ee5
+
+running 0 tests
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
 ```
 
-Nice! Our test passes, as we expected. Let's get rid of that warning for our `main`
-function. Change your `src/main.rs` to look like this:
+Nice! Our test passes, as we expected. Note how we didn't get the
+`main` warning this time? This is because `src/main.rs` didn't
+need recompiling, but we'll get that warning again if we
+change (and recompile) that file. Let's get rid of that
+warning; change your `src/main.rs` to look like this:
 
 ```{rust}
 #[cfg(not(test))]
 fn main() {
-    println!("Hello, world");
+    println!("Hello, world!")
 }
 ```
 
@@ -3062,21 +3049,24 @@ our tests, it sets things up so that `cfg(test)` is true. But we want to only
 include `main` when it's _not_ true. So we use `not` to negate things:
 `cfg(not(test))` will only compile our code when the `cfg(test)` is false.
 
-With this attribute, we won't get the warning:
+With this attribute we won't get the warning (even
+though `src/main.rs` gets recompiled this time):
 
 ```{notrust,ignore}
 $ cargo test
    Compiling testing v0.0.1 (file:///home/you/projects/testing)
-
-running 0 tests
-
-test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
-
+     Running target/lib-654ce120f310a3a5
 
 running 1 test
 test foo ... ok
 
 test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+
+     Running target/testing-6d7518593c7c3ee5
+
+running 0 tests
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
 ```
 
 Nice. Okay, let's write a real test now. Change your `tests/lib.rs`
@@ -3133,7 +3123,7 @@ extern crate testing;
 
 #[cfg(not(test))]
 fn main() {
-    println!("Hello, world");
+    println!("Hello, world!")
 }
 ```
 
@@ -3156,21 +3146,30 @@ Let's give it a run:
 ```{ignore,notrust}
 $ cargo test
    Compiling testing v0.0.1 (file:///home/you/projects/testing)
+     Running target/lib-654ce120f310a3a5
+
+running 1 test
+test math_checks_out ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+
+     Running target/testing-6d7518593c7c3ee5
 
 running 0 tests
 
 test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
 
+     Running target/testing-8a94b31f7fd2e8fe
 
 running 0 tests
 
 test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
 
+   Doc-tests testing
 
-running 1 test
-test math_checks_out ... ok
+running 0 tests
 
-test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
 ```
 
 Great! One test passed. We've got an integration test showing that our public
@@ -3196,21 +3195,30 @@ If you run `cargo test`, you should get the same output:
 ```{ignore,notrust}
 $ cargo test
    Compiling testing v0.0.1 (file:///home/you/projects/testing)
+     Running target/lib-654ce120f310a3a5
+
+running 1 test
+test math_checks_out ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+
+     Running target/testing-6d7518593c7c3ee5
 
 running 0 tests
 
 test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
 
+     Running target/testing-8a94b31f7fd2e8fe
 
 running 0 tests
 
 test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
 
+   Doc-tests testing
 
-running 1 test
-test math_checks_out ... ok
+running 0 tests
 
-test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
 ```
 
 If we tried to write a test for these two new functions, it wouldn't
@@ -3283,6 +3291,20 @@ Let's give it a shot:
 ```{ignore,notrust}
 $ cargo test
    Compiling testing v0.0.1 (file:///home/you/projects/testing)
+     Running target/lib-654ce120f310a3a5
+
+running 1 test
+test math_checks_out ... ok
+
+test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
+
+     Running target/testing-6d7518593c7c3ee5
+
+running 0 tests
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
+
+     Running target/testing-8a94b31f7fd2e8fe
 
 running 2 tests
 test test::test_times_four ... ok
@@ -3290,16 +3312,11 @@ test test::test_add_three ... ok
 
 test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured
 
+   Doc-tests testing
 
 running 0 tests
 
 test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
-
-
-running 1 test
-test math_checks_out ... ok
-
-test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
 ```
 
 Cool! We now have two tests of our internal functions. You'll note that there
@@ -3510,8 +3527,8 @@ everyone plays by these rules. At compile time, it verifies that none of these
 rules are broken. If our program compiles successfully, Rust can guarantee it
 is free of data races and other memory errors, and there is no runtime overhead
 for any of this. The borrow checker works only at compile time. If the borrow
-checker did find a problem, it will report a **lifetime error**, and your
-program will refuse to compile.
+checker did find a problem, it will report an error and your program will
+refuse to compile.
 
 That's a lot to take in. It's also one of the _most_ important concepts in
 all of Rust. Let's see this syntax in action:
@@ -3637,40 +3654,72 @@ pub fn as_maybe_owned(&self) -> MaybeOwned<'a> { ... }
 
 ## Boxes
 
-All of our references so far have been to variables we've created on the stack.
-In Rust, the simplest way to allocate heap variables is using a *box*.  To
-create a box, use the `box` keyword:
+Most of the types we've seen so far have a fixed size or number of components.
+The compiler needs this fact to lay out values in memory. However, some data
+structures, such as a linked list, do not have a fixed size. You might think to
+implement a linked list with an enum that's either a `Node` or the end of the
+list (`Nil`), like this:
+
+```{rust,ignore}
+enum List {             // error: illegal recursive enum type
+    Node(u32, List),
+    Nil
+}
+```
+
+But the compiler complains that the type is recursive, that is, it could be
+arbitrarily large. To remedy this, Rust provides a fixed-size container called
+a **box** that can hold any type. You can box up any value with the `box`
+keyword. Our boxed List gets the type `Box<List>` (more on the notation when we
+get to generics):
 
 ```{rust}
-let x = box 5i;
+enum List {
+    Node(u32, Box<List>),
+    Nil
+}
+
+fn main() {
+    let list = Node(0, box Node(1, box Nil));
+}
 ```
 
-This allocates an integer `5` on the heap, and creates a binding `x` that
-refers to it. The great thing about boxed pointers is that we don't have to
-manually free this allocation! If we write
+A box dynamically allocates memory to hold its contents. The great thing about
+Rust is that that memory is *automatically*, *efficiently*, and *predictably*
+deallocated when you're done with the box.
+
+A box is a pointer type, and you access what's inside using the `*` operator,
+just like regular references. This (rather silly) example dynamically allocates
+an integer `5` and makes `x` a pointer to it:
 
 ```{rust}
 {
     let x = box 5i;
-    // do stuff
+    println!("{}", *x);     // Prints 5
 }
 ```
 
-then Rust will automatically free `x` at the end of the block. This isn't
-because Rust has a garbage collector -- it doesn't. Instead, when `x` goes out
-of scope, Rust `free`s `x`. This Rust code will do the same thing as the
-following C code:
+The great thing about boxes is that we don't have to manually free this
+allocation! Instead, when `x` reaches the end of its lifetime -- in this case,
+when it goes out of scope at the end of the block -- Rust `free`s `x`. This
+isn't because Rust has a garbage collector (it doesn't). Instead, by tracking
+the ownership and lifetime of a variable (with a little help from you, the
+programmer), the compiler knows precisely when it is no longer used.
+
+The Rust code above will do the same thing as the following C code:
 
 ```{c,ignore}
 {
     int *x = (int *)malloc(sizeof(int));
-    // do stuff
+    if (!x) abort();
+    *x = 5;
+    printf("%d\n", *x);
     free(x);
 }
 ```
 
-This means we get the benefits of manual memory management, but the compiler
-ensures that we don't do something wrong. We can't forget to `free` our memory.
+We get the benefits of manual memory management, while ensuring we don't
+introduce any bugs. We can't forget to `free` our memory.
 
 Boxes are the sole owner of their contents, so you cannot take a mutable
 reference to them and then use the original box:
@@ -3706,48 +3755,50 @@ let mut x = box 5i;
 *x;
 ```
 
-## Rc and Arc
-
-Sometimes, you need to allocate something on the heap, but give out multiple
-references to the memory. Rust's `Rc<T>` (pronounced 'arr cee tee') and
-`Arc<T>` types (again, the `T` is for generics, we'll learn more later) provide
-you with this ability.  **Rc** stands for 'reference counted,' and **Arc** for
-'atomically reference counted.' This is how Rust keeps track of the multiple
-owners: every time we make a new reference to the `Rc<T>`, we add one to its
-internal 'reference count.' Every time a reference goes out of scope, we
-subtract one from the count. When the count is zero, the `Rc<T>` can be safely
-deallocated. `Arc<T>` is almost identical to `Rc<T>`, except for one thing: The
-'atomically' in 'Arc' means that increasing and decreasing the count uses a
-thread-safe mechanism to do so. Why two types? `Rc<T>` is faster, so if you're
-not in a multi-threaded scenario, you can have that advantage. Since we haven't
-talked about threading yet in Rust, we'll show you `Rc<T>` for the rest of this
-section.
+Boxes are simple and efficient pointers to dynamically allocated values with a
+single owner. They are useful for tree-like structures where the lifetime of a
+child depends solely on the lifetime of its (single) parent. If you need a
+value that must persist as long as any of several referrers, read on.
 
-To create an `Rc<T>`, use `Rc::new()`:
+## Rc and Arc
 
-```{rust}
-use std::rc::Rc;
+Sometimes, you need a variable that is referenced from multiple places
+(immutably!), lasting as long as any of those places, and disappearing when it
+is no longer referenced. For instance, in a graph-like data structure, a node
+might be referenced from all of its neighbors. In this case, it is not possible
+for the compiler to determine ahead of time when the value can be freed -- it
+needs a little run-time support.
 
-let x = Rc::new(5i);
-```
+Rust's **Rc** type provides shared ownership of a dynamically allocated value
+that is automatically freed at the end of its last owner's lifetime. (`Rc`
+stands for 'reference counted,' referring to the way these library types are
+implemented.) This provides more flexibility than single-owner boxes, but has
+some runtime overhead.
 
-To create a second reference, use the `.clone()` method:
+To create an `Rc` value, use `Rc::new()`. To create a second owner, use the
+`.clone()` method:
 
 ```{rust}
 use std::rc::Rc;
 
 let x = Rc::new(5i);
 let y = x.clone();
+
+println!("{} {}", *x, *y);      // Prints 5 5
 ```
 
-The `Rc<T>` will live as long as any of its references are alive. After they
-all go out of scope, the memory will be `free`d.
+The `Rc` will live as long as any of its owners are alive. After that, the
+memory will be `free`d.
+
+**Arc** is an 'atomically reference counted' value, identical to `Rc` except
+that ownership can be safely shared among multiple threads. Why two types?
+`Arc` has more overhead, so if you're not in a multi-threaded scenario, you
+don't have to pay the price.
 
-If you use `Rc<T>` or `Arc<T>`, you have to be careful about introducing
-cycles. If you have two `Rc<T>`s that point to each other, the reference counts
-will never drop to zero, and you'll have a memory leak. To learn more, check
-out [the section on `Rc<T>` and `Arc<T>` in the pointers
-guide](guide-pointers.html#rc-and-arc).
+If you use `Rc` or `Arc`, you have to be careful about introducing cycles. If
+you have two `Rc`s that point to each other, they will happily keep each other
+alive forever, creating a memory leak. To learn more, check out [the section on
+`Rc` and `Arc` in the pointers guide](guide-pointers.html#rc-and-arc).
 
 # Patterns
 
@@ -4010,8 +4061,8 @@ syntax.
 
 # Closures
 
-So far, we've made lots of functions in Rust. But we've given them all names.
-Rust also allows us to create anonymous functions too. Rust's anonymous
+So far, we've made lots of functions in Rust, but we've given them all names.
+Rust also allows us to create anonymous functions. Rust's anonymous
 functions are called **closure**s. By themselves, closures aren't all that
 interesting, but when you combine them with functions that take closures as
 arguments, really powerful things are possible.
@@ -4040,7 +4091,7 @@ don't need to declare one. This is different from named functions, which
 default to returning unit (`()`).
 
 There's one big difference between a closure and named functions, and it's in
-the name: a closure "closes over its environment." What's that mean? It means
+the name: a closure "closes over its environment." What does that mean? It means
 this:
 
 ```{rust}
@@ -4056,8 +4107,8 @@ fn main() {
 The `||` syntax means this is an anonymous closure that takes no arguments.
 Without it, we'd just have a block of code in `{}`s.
 
-In other words, a closure has access to variables in the scope that it's
-defined. The closure borrows any variables that it uses. This will error:
+In other words, a closure has access to variables in the scope where it's
+defined. The closure borrows any variables it uses, so this will error:
 
 ```{rust,ignore}
 fn main() {
@@ -4081,7 +4132,7 @@ let p = proc() { x * x };
 println!("{}", p()); // prints 25
 ```
 
-Procs have a big difference from closures: they may only be called once. This
+There is a big difference between procs and closures: procs may only be called once. This
 will error when we try to compile:
 
 ```{rust,ignore}
@@ -4174,10 +4225,10 @@ before. And we pass in our `x` argument to each one. Hence 'twice.'
 If you do the math, `(5 * 5) + (5 * 5) == 50`, so that's the output we get.
 
 Play around with this concept until you're comfortable with it. Rust's standard
-library uses lots of closures, where appropriate, so you'll be using
+library uses lots of closures where appropriate, so you'll be using
 this technique a lot.
 
-If we didn't want to give `square` a name, we could also just define it inline.
+If we didn't want to give `square` a name, we could just define it inline.
 This example is the same as the previous one:
 
 ```{rust}
@@ -4205,12 +4256,12 @@ fn main() {
 }
 ```
 
-Doing this is not particularly common, but every once in a while, it's useful.
+Doing this is not particularly common, but it's useful every once in a while.
 
 That's all you need to get the hang of closures! Closures are a little bit
-strange at first, but once you're used to using them, you'll miss them in any
-language that doesn't have them. Passing functions to other functions is
-incredibly powerful. Next, let's look at one of those things: iterators.
+strange at first, but once you're used to them, you'll miss them
+in other languages. Passing functions to other functions is
+incredibly powerful, as you will see in the following chapter about iterators.
 
 # Iterators
 
@@ -4220,7 +4271,7 @@ Remember Rust's `for` loop? Here's an example:
 
 ```{rust}
 for x in range(0i, 10i) {
-    println!("{:d}", x);
+    println!("{}", x);
 }
 ```
 
@@ -4353,7 +4404,7 @@ is one:
 
 ```{rust}
 let greater_than_forty_two = range(0i, 100i)
-                             .find(|x| *x >= 42);
+                             .find(|x| *x > 42);
 
 match greater_than_forty_two {
     Some(_) => println!("We got some numbers!"),
@@ -4474,7 +4525,7 @@ range(1i, 100i).map(|x| x + 1i);
 
 `map` is called upon another iterator, and produces a new iterator where each
 element reference has the closure it's been given as an argument called on it.
-So this would give us the numbers from `2-101`. Well, almost! If you
+So this would give us the numbers from `2-100`. Well, almost! If you
 compile the example, you'll get a warning:
 
 ```{notrust,ignore}
@@ -4494,9 +4545,10 @@ range(1i, 100i).map(|x| println!("{}", x));
 If you are trying to execute a closure on an iterator for its side effects,
 just use `for` instead.
 
-There are tons of interesting iterator adapters. `take(n)` will get the
-first `n` items out of an iterator, and return them as a list. Let's
-try it out with our infinite iterator from before, `count()`:
+There are tons of interesting iterator adapters. `take(n)` will return an
+iterator over the next `n` elements of the original iterator, note that this
+has no side effect on the original iterator. Let's try it out with our infinite
+iterator from before, `count()`:
 
 ```{rust}
 for i in std::iter::count(1i, 5i).take(5) {
@@ -5161,17 +5213,17 @@ immediately.
 
 ## Success and failure
 
-Tasks don't always succeed, they can also fail. A task that wishes to fail
-can call the `fail!` macro, passing a message:
+Tasks don't always succeed, they can also panic. A task that wishes to panic 
+can call the `panic!` macro, passing a message:
 
 ```{rust}
 spawn(proc() {
-    fail!("Nope.");
+    panic!("Nope.");
 });
 ```
 
-If a task fails, it is not possible for it to recover. However, it can
-notify other tasks that it has failed. We can do this with `task::try`:
+If a task panics, it is not possible for it to recover. However, it can
+notify other tasks that it has panicked. We can do this with `task::try`:
 
 ```{rust}
 use std::task;
@@ -5181,14 +5233,14 @@ let result = task::try(proc() {
     if rand::random() {
         println!("OK");
     } else {
-        fail!("oops!");
+        panic!("oops!");
     }
 });
 ```
 
-This task will randomly fail or succeed. `task::try` returns a `Result`
+This task will randomly panic or succeed. `task::try` returns a `Result`
 type, so we can handle the response like any other computation that may
-fail.
+panic.
 
 # Macros
 
@@ -5288,9 +5340,9 @@ There are two circumstances where Rust's safety provisions don't work well.
 The first is when interfacing with C code, and the second is when building
 certain kinds of abstractions.
 
-Rust has support for FFI (which you can read about in the [FFI
-Guide](guide-ffi.html)), but can't guarantee that the C code will be safe.
-Therefore, Rust marks such functions with the `unsafe`
+Rust has support for [FFI](http://en.wikipedia.org/wiki/Foreign_function_interface)
+(which you can read about in the [FFI Guide](guide-ffi.html)), but can't guarantee
+that the C code will be safe. Therefore, Rust marks such functions with the `unsafe`
 keyword, which indicates that the function may not behave properly.
 
 Second, if you'd like to create some sort of shared-memory data structure, Rust