]> git.lizzy.rs Git - rust.git/commitdiff
rollup merge of #18321 : chastell/guide_refresh_testing_output
authorAlex Crichton <alex@alexcrichton.com>
Mon, 27 Oct 2014 16:07:40 +0000 (09:07 -0700)
committerAlex Crichton <alex@alexcrichton.com>
Mon, 27 Oct 2014 22:12:29 +0000 (15:12 -0700)
1  2 
src/doc/guide.md

diff --combined src/doc/guide.md
index a399fde579c8a15d97a2c2953fa6b738c26aa2e2,cd7478938187a1e0bd82404f9c2f0216b39109f6..876157409c55714f4e75879df470a6379790947f
@@@ -1130,12 -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 +1301,7 @@@ Instead, it looks like this
  
  ```{rust}
  for x in range(0i, 10i) {
 -    println!("{:d}", x);
 +    println!("{}", x);
  }
  ```
  
@@@ -1408,7 -1408,7 +1408,7 @@@ iteration: This will only print the od
  for x in range(0i, 10i) {
      if x % 2 == 0 { continue; }
  
 -    println!("{:d}", x);
 +    println!("{}", x);
  }
  ```
  
@@@ -1677,12 -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 +1793,7 @@@ Finally, Cargo generated a hello, worl
  
  ```{rust}
  fn main() {
-     println!("Hello, world!");
+     println!("Hello, world!")
  }
  ```
  
@@@ -2682,12 -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 +2721,7 @@@ fn main() 
  
  mod hello {
      fn print_hello() {
-         println!("Hello, world!");
+         println!("Hello, world!")
      }
  }
  ```
@@@ -2744,7 -2744,7 +2744,7 @@@ fn main() 
  
  mod hello {
      pub fn print_hello() {
-         println!("Hello, world!");
+         println!("Hello, world!")
      }
  }
  ```
@@@ -2921,15 -2921,11 +2921,11 @@@ it `false`, so this test should fail. L
  ```{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 +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 +2956,9 @@@ You can run all of your tests with `car
  `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 +2970,8 @@@ We'll turn this lint off for just this 
  output.
  
  ```{notrust,ignore}
- running 0 tests
+      Running target/lib-654ce120f310a3a5
  
- test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured
- ```
- 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 +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 +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 +3049,24 @@@ our tests, it sets things up so that `c
  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 +3123,7 @@@ extern crate testing
  
  #[cfg(not(test))]
  fn main() {
-     println!("Hello, world");
+     println!("Hello, world!")
  }
  ```
  
@@@ -3156,21 -3146,30 +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 +3195,30 @@@ If you run `cargo test`, you should ge
  ```{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 +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 +3312,11 @@@ test test::test_add_three ... o
  
  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
@@@ -3466,14 -3483,13 +3483,14 @@@ for destroying that resource as well. G
  right now, let's discuss this in the context of memory allocation, though
  it applies to other resources as well.
  
 -When you allocate heap memory, you need a mechanism to free that memory.  Many
 -languages let the programmer control the allocation, and then use a garbage
 -collector to handle the deallocation. This is a valid, time-tested strategy,
 -but it's not without its drawbacks. Because the programmer does not have to
 -think as much about deallocation, allocation becomes something commonplace,
 -because it's easy. And if you need precise control over when something is
 -deallocated, leaving it up to your runtime can make this difficult.
 +When you allocate heap memory, you need a mechanism to free that memory. Many
 +languages use a garbage collector to handle deallocation. This is a valid,
 +time-tested strategy, but it's not without its drawbacks: it adds overhead, and
 +can lead to unpredictable pauses in execution. Because the programmer does not
 +have to think as much about deallocation, allocation becomes something
 +commonplace, leading to more memory usage. And if you need precise control
 +over when something is deallocated, leaving it up to your runtime can make this
 +difficult.
  
  Rust chooses a different path, and that path is called **ownership**. Any
  binding that creates a resource is the **owner** of that resource.
@@@ -3499,19 -3515,17 +3516,19 @@@ memory. The length of time that the bor
  from you is called a **lifetime**.
  
  If two distinct bindings share a pointer, and the memory that pointer points to
 -is immutable, then there are no problems. But if it's mutable, both pointers
 -can attempt to write to the memory at the same time, causing a **race
 -condition**. Therefore, if someone wants to mutate something that they've
 -borrowed from you, you must not have lent out that pointer to anyone else.
 +is immutable, then there are no problems. But if it's mutable, the result of
 +changing it can vary unpredictably depending on who happens to access it first,
 +which is called a **race condition**. To avoid this, if someone wants to mutate
 +something that they've borrowed from you, you must not have lent out that
 +pointer to anyone else.
  
  Rust has a sophisticated system called the **borrow checker** to make sure that
  everyone plays by these rules. At compile time, it verifies that none of these
 -rules are broken. If there's no problem, our program compiles successfully, 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.
 +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.
  
  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,72 -3651,40 +3654,72 @@@ pub fn as_maybe_owned(&self) -> MaybeOw
  
  ## 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:
@@@ -3738,50 -3720,48 +3755,50 @@@ let mut x = box 5i
  *x;
  ```
  
 +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.
 +
  ## 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.
 -
 -To create an `Rc<T>`, use `Rc::new()`:
 +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.
  
 -```{rust}
 -use std::rc::Rc;
 +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.
  
 -let x = Rc::new(5i);
 -```
 -
 -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.
  
 -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).
 +**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` 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
  
@@@ -4254,7 -4234,7 +4271,7 @@@ Remember Rust's `for` loop? Here's an e
  
  ```{rust}
  for x in range(0i, 10i) {
 -    println!("{:d}", x);
 +    println!("{}", x);
  }
  ```
  
@@@ -4387,7 -4367,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!"),
@@@ -4508,7 -4488,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}