auto merge of #21300 : steveklabnik/rust/rollup, r=steveklabnik

manual rollup to fix some conflicts and diagnose why the test is failing...
This commit is contained in:
bors 2015-01-17 20:31:08 +00:00
commit f4f10dba29
50 changed files with 604 additions and 457 deletions

View File

@ -1,4 +1,4 @@
Copyright (c) 2014 The Rust Project Developers
Copyright (c) 2015 The Rust Project Developers
Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated

View File

@ -52,7 +52,7 @@
TARGET_CRATES := libc std flate arena term \
serialize getopts collections test rand \
log regex graphviz core rbml alloc \
unicode
unicode rustc_bitflags
RUSTC_CRATES := rustc rustc_typeck rustc_borrowck rustc_resolve rustc_driver \
rustc_trans rustc_back rustc_llvm rustc_privacy
HOST_CRATES := syntax $(RUSTC_CRATES) rustdoc fmt_macros
@ -64,7 +64,8 @@ DEPS_libc := core
DEPS_unicode := core
DEPS_alloc := core libc native:jemalloc
DEPS_std := core libc rand alloc collections unicode \
native:rust_builtin native:backtrace native:rustrt_native
native:rust_builtin native:backtrace native:rustrt_native \
rustc_bitflags
DEPS_graphviz := std
DEPS_syntax := std term serialize log fmt_macros arena libc
DEPS_rustc_driver := arena flate getopts graphviz libc rustc rustc_back rustc_borrowck \
@ -83,6 +84,7 @@ DEPS_rustc_llvm := native:rustllvm libc std
DEPS_rustc_back := std syntax rustc_llvm flate log libc
DEPS_rustdoc := rustc rustc_driver native:hoedown serialize getopts \
test
DEPS_rustc_bitflags := core
DEPS_flate := std native:miniz
DEPS_arena := std
DEPS_graphviz := std
@ -114,6 +116,7 @@ ONLY_RLIB_alloc := 1
ONLY_RLIB_rand := 1
ONLY_RLIB_collections := 1
ONLY_RLIB_unicode := 1
ONLY_RLIB_rustc_bitflags := 1
################################################################################
# You should not need to edit below this line

View File

@ -424,11 +424,11 @@ Let's see an example. This Rust code will not compile:
use std::thread::Thread;
fn main() {
let mut numbers = vec![1i, 2i, 3i];
let mut numbers = vec![1is, 2, 3];
for i in range(0u, 3u) {
for i in 0..3 {
Thread::spawn(move || {
for j in range(0, 3) { numbers[j] += 1 }
for j in 0..3 { numbers[j] += 1 }
});
}
}
@ -438,15 +438,15 @@ It gives us this error:
```text
6:71 error: capture of moved value: `numbers`
for j in range(0, 3) { numbers[j] += 1 }
^~~~~~~
for j in 0..3 { numbers[j] += 1 }
^~~~~~~
7:50 note: `numbers` moved into closure environment here
spawn(move || {
for j in range(0, 3) { numbers[j] += 1 }
for j in 0..3 { numbers[j] += 1 }
});
6:79 error: cannot assign to immutable dereference (dereference is implicit, due to indexing)
for j in range(0, 3) { numbers[j] += 1 }
^~~~~~~~~~~~~~~
for j in 0..3 { numbers[j] += 1 }
^~~~~~~~~~~~~~~
```
It mentions that "numbers moved into closure environment". Because we
@ -478,9 +478,9 @@ use std::thread::Thread;
use std::sync::{Arc,Mutex};
fn main() {
let numbers = Arc::new(Mutex::new(vec![1i, 2i, 3i]));
let numbers = Arc::new(Mutex::new(vec![1is, 2, 3]));
for i in range(0u, 3u) {
for i in 0..3 {
let number = numbers.clone();
Thread::spawn(move || {
let mut array = number.lock().unwrap();
@ -541,12 +541,12 @@ safety check that makes this an error about moved values:
use std::thread::Thread;
fn main() {
let vec = vec![1i, 2, 3];
let vec = vec![1is, 2, 3];
for i in range(0u, 3) {
for i in 0us..3 {
Thread::spawn(move || {
println!("{}", vec[i]);
}).detach();
});
}
}
```
@ -557,9 +557,9 @@ you can remove it. As an example, this is a poor way to iterate through
a vector:
```{rust}
let vec = vec![1i, 2, 3];
let vec = vec![1, 2, 3];
for i in range(0u, vec.len()) {
for i in 0..vec.len() {
println!("{}", vec[i]);
}
```
@ -569,7 +569,7 @@ that we don't try to access an invalid index. However, we can remove this
while retaining safety. The answer is iterators:
```{rust}
let vec = vec![1i, 2, 3];
let vec = vec![1, 2, 3];
for x in vec.iter() {
println!("{}", x);

View File

@ -1413,6 +1413,27 @@ a = Animal::Cat { name: "Spotty".to_string(), weight: 2.7 };
In this example, `Cat` is a _struct-like enum variant_,
whereas `Dog` is simply called an enum variant.
Enums have a discriminant. You can assign them explicitly:
```
enum Foo {
Bar = 123,
}
```
If a discriminant isn't assigned, they start at zero, and add one for each
variant, in order.
You can cast an enum to get this value:
```
# enum Foo { Bar = 123 }
let x = Foo::Bar as u32; // x is now 123u32
```
This only works as long as none of the variants have data attached. If
it were `Bar(i32)`, this is disallowed.
### Constant items
```{.ebnf .gram}

View File

@ -5,7 +5,7 @@ things. The most basic is the *array*, a fixed-size list of elements of the
same type. By default, arrays are immutable.
```{rust}
let a = [1, 2, 3]; // a: [i32; 3]
let a = [1, 2, 3]; // a: [i32; 3]
let mut m = [1, 2, 3]; // mut m: [i32; 3]
```
@ -68,7 +68,7 @@ let mut nums = vec![1, 2, 3]; // mut nums: Vec<i32>
nums.push(4);
println!("The length of nums is now {}", nums.len()); // Prints 4
println!("The length of nums is now {}", nums.len()); // Prints 4
```
Vectors have many more useful methods.
@ -82,10 +82,10 @@ arrays:
```{rust}
let a = [0, 1, 2, 3, 4];
let middle = &a[1..4]; // A slice of a: just the elements 1, 2, and 3
let middle = &a[1..4]; // A slice of a: just the elements 1, 2, and 3
for e in middle.iter() {
println!("{}", e); // Prints 1, 2, 3
println!("{}", e); // Prints 1, 2, 3
}
```

View File

@ -51,7 +51,7 @@ arity and contained types.
```rust
let mut x = (1, 2); // x: (i32, i32)
let y = (2, 3); // y: (i32, i32)
let y = (2, 3); // y: (i32, i32)
x = y;
```
@ -156,7 +156,7 @@ These two will not be equal, even if they have the same values:
```{rust}
# struct Color(i32, i32, i32);
# struct Point(i32, i32, i32);
let black = Color(0, 0, 0);
let black = Color(0, 0, 0);
let origin = Point(0, 0, 0);
```
@ -297,7 +297,7 @@ enum StringResult {
}
```
Where a `StringResult` is either a `StringResult::StringOK`, with the result of
a computation, or an `StringResult::ErrorReason` with a `String` explaining
a computation, or a `StringResult::ErrorReason` with a `String` explaining
what caused the computation to fail. These kinds of `enum`s are actually very
useful and are even part of the standard library.

View File

@ -1,4 +1,4 @@
% The Rust Crates and Modules Guide
% Crates and Modules
When a project starts getting large, it's considered a good software
engineering practice to split it up into a bunch of smaller pieces, and then

View File

@ -1,4 +1,4 @@
% Error Handling in Rust
% Error Handling
> The best-laid plans of mice and men
> Often go awry
@ -60,12 +60,12 @@ fn probability(_: &Event) -> f64 {
fn descriptive_probability(event: Event) -> &'static str {
match probability(&event) {
1.00 => "certain",
0.00 => "impossible",
1.00 => "certain",
0.00 => "impossible",
0.00 ... 0.25 => "very unlikely",
0.25 ... 0.50 => "unlikely",
0.50 ... 0.75 => "likely",
0.75 ... 1.00 => "very likely",
0.75 ... 1.00 => "very likely",
}
}
@ -97,12 +97,12 @@ fn probability(_: &Event) -> f64 {
fn descriptive_probability(event: Event) -> &'static str {
match probability(&event) {
1.00 => "certain",
0.00 => "impossible",
1.00 => "certain",
0.00 => "impossible",
0.00 ... 0.25 => "very unlikely",
0.25 ... 0.50 => "unlikely",
0.50 ... 0.75 => "likely",
0.75 ... 1.00 => "very likely",
0.75 ... 1.00 => "very likely",
_ => unreachable!()
}
}

View File

@ -1,4 +1,4 @@
% The Rust Foreign Function Interface Guide
% Foreign Function Interface
# Introduction
@ -11,7 +11,7 @@ snappy includes a C interface (documented in
The following is a minimal example of calling a foreign function which will
compile if snappy is installed:
~~~~no_run
```no_run
extern crate libc;
use libc::size_t;
@ -24,7 +24,7 @@ fn main() {
let x = unsafe { snappy_max_compressed_length(100) };
println!("max compressed length of a 100 byte buffer: {}", x);
}
~~~~
```
The `extern` block is a list of function signatures in a foreign library, in
this case with the platform's C ABI. The `#[link(...)]` attribute is used to
@ -44,7 +44,7 @@ keeping the binding correct at runtime.
The `extern` block can be extended to cover the entire snappy API:
~~~~no_run
```no_run
extern crate libc;
use libc::{c_int, size_t};
@ -66,7 +66,7 @@ extern {
compressed_length: size_t) -> c_int;
}
# fn main() {}
~~~~
```
# Creating a safe interface
@ -79,7 +79,7 @@ vectors as pointers to memory. Rust's vectors are guaranteed to be a contiguous
length is number of elements currently contained, and the capacity is the total size in elements of
the allocated memory. The length is less than or equal to the capacity.
~~~~
```
# extern crate libc;
# use libc::{c_int, size_t};
# unsafe fn snappy_validate_compressed_buffer(_: *const u8, _: size_t) -> c_int { 0 }
@ -89,7 +89,7 @@ pub fn validate_compressed_buffer(src: &[u8]) -> bool {
snappy_validate_compressed_buffer(src.as_ptr(), src.len() as size_t) == 0
}
}
~~~~
```
The `validate_compressed_buffer` wrapper above makes use of an `unsafe` block, but it makes the
guarantee that calling it is safe for all inputs by leaving off `unsafe` from the function
@ -103,7 +103,7 @@ required capacity to hold the compressed output. The vector can then be passed t
`snappy_compress` function as an output parameter. An output parameter is also passed to retrieve
the true length after compression for setting the length.
~~~~
```
# extern crate libc;
# use libc::{size_t, c_int};
# unsafe fn snappy_compress(a: *const u8, b: size_t, c: *mut u8,
@ -116,20 +116,20 @@ pub fn compress(src: &[u8]) -> Vec<u8> {
let psrc = src.as_ptr();
let mut dstlen = snappy_max_compressed_length(srclen);
let mut dst = Vec::with_capacity(dstlen as uint);
let mut dst = Vec::with_capacity(dstlen as usize);
let pdst = dst.as_mut_ptr();
snappy_compress(psrc, srclen, pdst, &mut dstlen);
dst.set_len(dstlen as uint);
dst.set_len(dstlen as usize);
dst
}
}
~~~~
```
Decompression is similar, because snappy stores the uncompressed size as part of the compression
format and `snappy_uncompressed_length` will retrieve the exact buffer size required.
~~~~
```
# extern crate libc;
# use libc::{size_t, c_int};
# unsafe fn snappy_uncompress(compressed: *const u8,
@ -148,45 +148,22 @@ pub fn uncompress(src: &[u8]) -> Option<Vec<u8>> {
let mut dstlen: size_t = 0;
snappy_uncompressed_length(psrc, srclen, &mut dstlen);
let mut dst = Vec::with_capacity(dstlen as uint);
let mut dst = Vec::with_capacity(dstlen as usize);
let pdst = dst.as_mut_ptr();
if snappy_uncompress(psrc, srclen, pdst, &mut dstlen) == 0 {
dst.set_len(dstlen as uint);
dst.set_len(dstlen as usize);
Some(dst)
} else {
None // SNAPPY_INVALID_INPUT
}
}
}
~~~~
```
For reference, the examples used here are also available as an [library on
GitHub](https://github.com/thestinger/rust-snappy).
# Stack management
Rust threads by default run on a *large stack*. This is actually implemented as a
reserving a large segment of the address space and then lazily mapping in pages
as they are needed. When calling an external C function, the code is invoked on
the same stack as the rust stack. This means that there is no extra
stack-switching mechanism in place because it is assumed that the large stack
for the rust thread is plenty for the C function to have.
A planned future improvement (not yet implemented at the time of this writing)
is to have a guard page at the end of every rust stack. No rust function will
hit this guard page (due to Rust's usage of LLVM's `__morestack`). The intention
for this unmapped page is to prevent infinite recursion in C from overflowing
onto other rust stacks. If the guard page is hit, then the process will be
terminated with a message saying that the guard page was hit.
For normal external function usage, this all means that there shouldn't be any
need for any extra effort on a user's perspective. The C stack naturally
interleaves with the rust stack, and it's "large enough" for both to
interoperate. If, however, it is determined that a larger stack is necessary,
there are appropriate functions in the thread spawning API to control the size of
the stack of the thread which is spawned.
# Destructors
Foreign libraries often hand off ownership of resources to the calling code.
@ -208,7 +185,7 @@ A basic example is:
Rust code:
~~~~no_run
```no_run
extern fn callback(a: i32) {
println!("I'm called from C with value {0}", a);
}
@ -225,11 +202,11 @@ fn main() {
trigger_callback(); // Triggers the callback
}
}
~~~~
```
C code:
~~~~c
```c
typedef void (*rust_callback)(int32_t);
rust_callback cb;
@ -241,7 +218,7 @@ int32_t register_callback(rust_callback callback) {
void trigger_callback() {
cb(7); // Will call callback(7) in Rust
}
~~~~
```
In this example Rust's `main()` will call `trigger_callback()` in C,
which would, in turn, call back to `callback()` in Rust.
@ -261,7 +238,7 @@ referenced Rust object.
Rust code:
~~~~no_run
```no_run
#[repr(C)]
struct RustObject {
a: i32,
@ -292,11 +269,11 @@ fn main() {
trigger_callback();
}
}
~~~~
```
C code:
~~~~c
```c
typedef void (*rust_callback)(void*, int32_t);
void* cb_target;
rust_callback cb;
@ -310,7 +287,7 @@ int32_t register_callback(void* callback_target, rust_callback callback) {
void trigger_callback() {
cb(cb_target, 7); // Will call callback(&rustObject, 7) in Rust
}
~~~~
```
## Asynchronous callbacks
@ -389,13 +366,13 @@ 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
``` 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
@ -416,9 +393,9 @@ the compiler that the unsafety does not leak out of the block.
Unsafe functions, on the other hand, advertise it to the world. An unsafe function is written like
this:
~~~~
```
unsafe fn kaboom(ptr: *const int) -> int { *ptr }
~~~~
```
This function can only be called from an `unsafe` block or another `unsafe` function.
@ -428,7 +405,7 @@ Foreign APIs often export a global variable which could do something like track
global state. In order to access these variables, you declare them in `extern`
blocks with the `static` keyword:
~~~no_run
```no_run
extern crate libc;
#[link(name = "readline")]
@ -440,13 +417,13 @@ fn main() {
println!("You have readline version {} installed.",
rl_readline_version as int);
}
~~~
```
Alternatively, you may need to alter global state provided by a foreign
interface. To do this, statics can be declared with `mut` so rust can mutate
them.
~~~no_run
```no_run
extern crate libc;
use std::ffi::CString;
@ -463,7 +440,7 @@ fn main() {
// get a line, process it
unsafe { rl_prompt = ptr::null(); }
}
~~~
```
# Foreign calling conventions
@ -471,7 +448,7 @@ Most foreign code exposes a C ABI, and Rust uses the platform's C calling conven
calling foreign functions. Some foreign functions, most notably the Windows API, use other calling
conventions. Rust provides a way to tell the compiler which convention to use:
~~~~
```
extern crate libc;
#[cfg(all(target_os = "win32", target_arch = "x86"))]
@ -481,7 +458,7 @@ extern "stdcall" {
fn SetEnvironmentVariableA(n: *const u8, v: *const u8) -> libc::c_int;
}
# fn main() { }
~~~~
```
This applies to the entire `extern` block. The list of supported ABI constraints
are:
@ -541,3 +518,22 @@ with one of the non-nullable types, it is represented as a single pointer,
and the non-data variant is represented as the null pointer. So
`Option<extern "C" fn(c_int) -> c_int>` is how one represents a nullable
function pointer using the C ABI.
# Calling Rust code from C
You may wish to compile Rust code in a way so that it can be called from C. This is
fairly easy, but requires a few things:
```
#[no_mangle]
pub extern fn hello_rust() -> *const u8 {
"Hello, world!\0".as_ptr()
}
# fn main() {}
```
The `extern` makes this function adhere to the C calling convention, as
discussed above in "[Foreign Calling
Conventions](guide-ffi.html#foreign-calling-conventions)". The `no_mangle`
attribute turns off Rust's name mangling, so that it is easier to link to.

View File

@ -143,7 +143,7 @@ fn foo(x: i32) -> i32 {
```
The previous definition without `return` may look a bit strange if you haven't
worked in an expression-based language before, but it becomes intutive over
worked in an expression-based language before, but it becomes intuitive over
time. If this were production code, we wouldn't write it in that way anyway,
we'd write this:

View File

@ -5,7 +5,7 @@ multiple types of arguments. For example, remember our `OptionalInt` type?
```{rust}
enum OptionalInt {
Value(int),
Value(i32),
Missing,
}
```
@ -40,26 +40,26 @@ we substitute that type for the same type used in the generic. Here's an
example of using `Option<T>`, with some extra type annotations:
```{rust}
let x: Option<int> = Some(5i);
let x: Option<i32> = Some(5);
```
In the type declaration, we say `Option<int>`. Note how similar this looks to
`Option<T>`. So, in this particular `Option`, `T` has the value of `int`. On
the right-hand side of the binding, we do make a `Some(T)`, where `T` is `5i`.
Since that's an `int`, the two sides match, and Rust is happy. If they didn't
In the type declaration, we say `Option<i32>`. Note how similar this looks to
`Option<T>`. So, in this particular `Option`, `T` has the value of `i32`. On
the right-hand side of the binding, we do make a `Some(T)`, where `T` is `5`.
Since that's an `i32`, the two sides match, and Rust is happy. If they didn't
match, we'd get an error:
```{rust,ignore}
let x: Option<f64> = Some(5i);
// error: mismatched types: expected `core::option::Option<f64>`
// but found `core::option::Option<int>` (expected f64 but found int)
let x: Option<f64> = Some(5);
// error: mismatched types: expected `core::option::Option<f64>`,
// found `core::option::Option<_>` (expected f64 but found integral variable)
```
That doesn't mean we can't make `Option<T>`s that hold an `f64`! They just have to
match up:
```{rust}
let x: Option<int> = Some(5i);
let x: Option<i32> = Some(5);
let y: Option<f64> = Some(5.0f64);
```

View File

@ -297,9 +297,9 @@ fn main() {
println!("You guessed: {}", input);
match cmp(input, secret_number) {
Ordering::Less => println!("Too small!"),
Ordering::Less => println!("Too small!"),
Ordering::Greater => println!("Too big!"),
Ordering::Equal => println!("You win!"),
Ordering::Equal => println!("You win!"),
}
}
@ -352,9 +352,9 @@ fn main() {
println!("You guessed: {}", input);
match cmp(input, secret_number) {
Ordering::Less => println!("Too small!"),
Ordering::Less => println!("Too small!"),
Ordering::Greater => println!("Too big!"),
Ordering::Equal => println!("You win!"),
Ordering::Equal => println!("You win!"),
}
}
@ -422,8 +422,8 @@ In this case, we say `x` is a `u32` explicitly, so Rust is able to properly
tell `random()` what to generate. In a similar fashion, both of these work:
```{rust,ignore}
let input_num = "5".parse::<u32>(); // input_num: Option<u32>
let input_num: Option<u32> = "5".parse(); // input_num: Option<u32>
let input_num = "5".parse::<u32>(); // input_num: Option<u32>
let input_num: Option<u32> = "5".parse(); // input_num: Option<u32>
```
Anyway, with us now converting our input to a number, our code looks like this:
@ -450,9 +450,9 @@ fn main() {
println!("You guessed: {}", input_num);
match cmp(input_num, secret_number) {
Ordering::Less => println!("Too small!"),
Ordering::Less => println!("Too small!"),
Ordering::Greater => println!("Too big!"),
Ordering::Equal => println!("You win!"),
Ordering::Equal => println!("You win!"),
}
}
@ -499,7 +499,7 @@ fn main() {
let num = match input_num {
Some(num) => num,
None => {
None => {
println!("Please input a number!");
return;
}
@ -509,9 +509,9 @@ fn main() {
println!("You guessed: {}", num);
match cmp(num, secret_number) {
Ordering::Less => println!("Too small!"),
Ordering::Less => println!("Too small!"),
Ordering::Greater => println!("Too big!"),
Ordering::Equal => println!("You win!"),
Ordering::Equal => println!("You win!"),
}
}
@ -566,7 +566,7 @@ fn main() {
let num = match input_num {
Some(num) => num,
None => {
None => {
println!("Please input a number!");
return;
}
@ -576,9 +576,9 @@ fn main() {
println!("You guessed: {}", num);
match cmp(num, secret_number) {
Ordering::Less => println!("Too small!"),
Ordering::Less => println!("Too small!"),
Ordering::Greater => println!("Too big!"),
Ordering::Equal => println!("You win!"),
Ordering::Equal => println!("You win!"),
}
}
@ -642,7 +642,7 @@ fn main() {
let num = match input_num {
Some(num) => num,
None => {
None => {
println!("Please input a number!");
return;
}
@ -652,9 +652,9 @@ fn main() {
println!("You guessed: {}", num);
match cmp(num, secret_number) {
Ordering::Less => println!("Too small!"),
Ordering::Less => println!("Too small!"),
Ordering::Greater => println!("Too big!"),
Ordering::Equal => println!("You win!"),
Ordering::Equal => println!("You win!"),
}
}
}
@ -718,7 +718,7 @@ fn main() {
let num = match input_num {
Some(num) => num,
None => {
None => {
println!("Please input a number!");
return;
}
@ -728,9 +728,9 @@ fn main() {
println!("You guessed: {}", num);
match cmp(num, secret_number) {
Ordering::Less => println!("Too small!"),
Ordering::Less => println!("Too small!"),
Ordering::Greater => println!("Too big!"),
Ordering::Equal => {
Ordering::Equal => {
println!("You win!");
return;
},
@ -774,7 +774,7 @@ fn main() {
let num = match input_num {
Some(num) => num,
None => {
None => {
println!("Please input a number!");
continue;
}
@ -784,9 +784,9 @@ fn main() {
println!("You guessed: {}", num);
match cmp(num, secret_number) {
Ordering::Less => println!("Too small!"),
Ordering::Less => println!("Too small!"),
Ordering::Greater => println!("Too big!"),
Ordering::Equal => {
Ordering::Equal => {
println!("You win!");
return;
},
@ -851,7 +851,7 @@ fn main() {
let num = match input_num {
Some(num) => num,
None => {
None => {
println!("Please input a number!");
continue;
}
@ -861,9 +861,9 @@ fn main() {
println!("You guessed: {}", num);
match cmp(num, secret_number) {
Ordering::Less => println!("Too small!"),
Ordering::Less => println!("Too small!"),
Ordering::Greater => println!("Too big!"),
Ordering::Equal => {
Ordering::Equal => {
println!("You win!");
return;
},

View File

@ -5,7 +5,7 @@ Let's talk about loops.
Remember Rust's `for` loop? Here's an example:
```{rust}
for x in range(0i, 10i) {
for x in range(0, 10) {
println!("{}", x);
}
```
@ -17,7 +17,7 @@ call the `.next()` method on repeatedly, and it gives us a sequence of things.
Like this:
```{rust}
let mut range = range(0i, 10i);
let mut range = range(0, 10);
loop {
match range.next() {
@ -32,8 +32,8 @@ loop {
We make a mutable binding to the return value of `range`, which is our iterator.
We then `loop`, with an inner `match`. This `match` is used on the result of
`range.next()`, which gives us a reference to the next value of the iterator.
`next` returns an `Option<int>`, in this case, which will be `Some(int)` when
we have a value and `None` once we run out. If we get `Some(int)`, we print it
`next` returns an `Option<i32>`, in this case, which will be `Some(i32)` when
we have a value and `None` once we run out. If we get `Some(i32)`, we print it
out, and if we get `None`, we `break` out of the loop.
This code sample is basically the same as our `for` loop version. The `for`
@ -50,9 +50,9 @@ primitive. For example, if you needed to iterate over the contents of
a vector, you may be tempted to write this:
```{rust}
let nums = vec![1i, 2i, 3i];
let nums = vec![1, 2, 3];
for i in range(0u, nums.len()) {
for i in range(0, nums.len()) {
println!("{}", nums[i]);
}
```
@ -62,7 +62,7 @@ vectors returns an iterator which iterates through a reference to each element
of the vector in turn. So write this:
```{rust}
let nums = vec![1i, 2i, 3i];
let nums = vec![1, 2, 3];
for num in nums.iter() {
println!("{}", num);
@ -79,12 +79,12 @@ very common with iterators: we can ignore unnecessary bounds checks, but still
know that we're safe.
There's another detail here that's not 100% clear because of how `println!`
works. `num` is actually of type `&int`. That is, it's a reference to an `int`,
not an `int` itself. `println!` handles the dereferencing for us, so we don't
works. `num` is actually of type `&i32`. That is, it's a reference to an `i32`,
not an `i32` itself. `println!` handles the dereferencing for us, so we don't
see it. This code works fine too:
```{rust}
let nums = vec![1i, 2i, 3i];
let nums = vec![1, 2, 3];
for num in nums.iter() {
println!("{}", *num);
@ -118,7 +118,7 @@ The most common consumer is `collect()`. This code doesn't quite compile,
but it shows the intention:
```{rust,ignore}
let one_to_one_hundred = range(1i, 101i).collect();
let one_to_one_hundred = range(1, 101).collect();
```
As you can see, we call `collect()` on our iterator. `collect()` takes
@ -128,7 +128,7 @@ type of things you want to collect, and so you need to let it know.
Here's the version that does compile:
```{rust}
let one_to_one_hundred = range(1i, 101i).collect::<Vec<int>>();
let one_to_one_hundred = range(1, 101).collect::<Vec<i32>>();
```
If you remember, the `::<>` syntax allows us to give a type hint,
@ -138,12 +138,12 @@ and so we tell it that we want a vector of integers.
is one:
```{rust}
let greater_than_forty_two = range(0i, 100i)
let greater_than_forty_two = range(0, 100)
.find(|x| *x > 42);
match greater_than_forty_two {
Some(_) => println!("We got some numbers!"),
None => println!("No numbers found :("),
None => println!("No numbers found :("),
}
```
@ -155,8 +155,8 @@ element, `find` returns an `Option` rather than the element itself.
Another important consumer is `fold`. Here's what it looks like:
```{rust}
let sum = range(1i, 4i)
.fold(0i, |sum, x| sum + x);
let sum = range(1, 4)
.fold(0, |sum, x| sum + x);
```
`fold()` is a consumer that looks like this:
@ -172,24 +172,24 @@ in this iterator:
| base | accumulator | element | closure result |
|------|-------------|---------|----------------|
| 0i | 0i | 1i | 1i |
| 0i | 1i | 2i | 3i |
| 0i | 3i | 3i | 6i |
| 0 | 0 | 1 | 1 |
| 0 | 1 | 2 | 3 |
| 0 | 3 | 3 | 6 |
We called `fold()` with these arguments:
```{rust}
# range(1i, 4i)
.fold(0i, |sum, x| sum + x);
# range(1, 4)
.fold(0, |sum, x| sum + x);
```
So, `0i` is our base, `sum` is our accumulator, and `x` is our element. On the
first iteration, we set `sum` to `0i`, and `x` is the first element of `nums`,
`1i`. We then add `sum` and `x`, which gives us `0i + 1i = 1i`. On the second
So, `0` is our base, `sum` is our accumulator, and `x` is our element. On the
first iteration, we set `sum` to `0`, and `x` is the first element of `nums`,
`1`. We then add `sum` and `x`, which gives us `0 + 1 = 1`. On the second
iteration, that value becomes our accumulator, `sum`, and the element is
the second element of the array, `2i`. `1i + 2i = 3i`, and so that becomes
the second element of the array, `2`. `1 + 2 = 3`, and so that becomes
the value of the accumulator for the last iteration. On that iteration,
`x` is the last element, `3i`, and `3i + 3i = 6i`, which is our final
`x` is the last element, `3`, and `3 + 3 = 6`, which is our final
result for our sum. `1 + 2 + 3 = 6`, and that's the result we got.
Whew. `fold` can be a bit strange the first few times you see it, but once it
@ -210,14 +210,14 @@ This code, for example, does not actually generate the numbers
`1-100`, and just creates a value that represents the sequence:
```{rust}
let nums = range(1i, 100i);
let nums = range(1, 100);
```
Since we didn't do anything with the range, it didn't generate the sequence.
Let's add the consumer:
```{rust}
let nums = range(1i, 100i).collect::<Vec<int>>();
let nums = range(1, 100).collect::<Vec<i32>>();
```
Now, `collect()` will require that `range()` give it some numbers, and so
@ -228,7 +228,7 @@ which you've used before. `iter()` can turn a vector into a simple iterator
that gives you each element in turn:
```{rust}
let nums = [1i, 2i, 3i];
let nums = [1, 2, 3];
for num in nums.iter() {
println!("{}", num);
@ -239,12 +239,12 @@ These two basic iterators should serve you well. There are some more
advanced iterators, including ones that are infinite. Like `count`:
```{rust}
std::iter::count(1i, 5i);
std::iter::count(1, 5);
```
This iterator counts up from one, adding five each time. It will give
you a new integer every time, forever (well, technically, until it reaches the
maximum number representable by an `int`). But since iterators are lazy,
maximum number representable by an `i32`). But since iterators are lazy,
that's okay! You probably don't want to use `collect()` on it, though...
That's enough about iterators. Iterator adapters are the last concept
@ -256,7 +256,7 @@ we need to talk about with regards to iterators. Let's get to it!
a new iterator. The simplest one is called `map`:
```{rust,ignore}
range(1i, 100i).map(|x| x + 1i);
range(1, 100).map(|x| x + 1);
```
`map` is called upon another iterator, and produces a new iterator where each
@ -267,7 +267,7 @@ compile the example, you'll get a warning:
```{notrust,ignore}
warning: unused result which must be used: iterator adaptors are lazy and
do nothing unless consumed, #[warn(unused_must_use)] on by default
range(1i, 100i).map(|x| x + 1i);
range(1, 100).map(|x| x + 1);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
```
@ -275,7 +275,7 @@ Laziness strikes again! That closure will never execute. This example
doesn't print any numbers:
```{rust,ignore}
range(1i, 100i).map(|x| println!("{}", x));
range(1, 100).map(|x| println!("{}", x));
```
If you are trying to execute a closure on an iterator for its side effects,
@ -287,7 +287,7 @@ 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) {
for i in std::iter::count(1, 5).take(5) {
println!("{}", i);
}
```
@ -307,7 +307,7 @@ returns `true` or `false`. The new iterator `filter()` produces
only the elements that that closure returns `true` for:
```{rust}
for i in range(1i, 100i).filter(|&x| x % 2 == 0) {
for i in range(1, 100).filter(|&x| x % 2 == 0) {
println!("{}", i);
}
```
@ -322,11 +322,11 @@ You can chain all three things together: start with an iterator, adapt it
a few times, and then consume the result. Check it out:
```{rust}
range(1i, 1000i)
range(1, 1000)
.filter(|&x| x % 2 == 0)
.filter(|&x| x % 3 == 0)
.take(5)
.collect::<Vec<int>>();
.collect::<Vec<i32>>();
```
This will give you a vector containing `6`, `12`, `18`, `24`, and `30`.

View File

@ -54,7 +54,7 @@ The other kind of looping construct in Rust is the `while` loop. It looks like
this:
```{rust}
let mut x = 5u32; // mut x: u32
let mut x = 5; // mut x: u32
let mut done = false; // mut done: bool
while !done {
@ -91,7 +91,7 @@ can do with safety and code generation, so you should always prefer
Let's take a look at that `while` loop we had earlier:
```{rust}
let mut x = 5u32;
let mut x = 5;
let mut done = false;
while !done {
@ -108,7 +108,7 @@ modifying iteration: `break` and `continue`.
In this case, we can write the loop in a better way with `break`:
```{rust}
let mut x = 5u32;
let mut x = 5;
loop {
x += x - 3;

View File

@ -1,4 +1,4 @@
% The Rust Macros Guide
% Macros
# Introduction
@ -11,8 +11,8 @@ which both pattern-match on their input and both return early in one case,
doing nothing otherwise:
~~~~
# enum T { SpecialA(uint), SpecialB(uint) }
# fn f() -> uint {
# enum T { SpecialA(u32), SpecialB(u32) }
# fn f() -> u32 {
# let input_1 = T::SpecialA(0);
# let input_2 = T::SpecialA(0);
match input_1 {
@ -24,7 +24,7 @@ match input_2 {
T::SpecialB(x) => { return x; }
_ => {}
}
# return 0u;
# return 0;
# }
~~~~
@ -37,8 +37,8 @@ lightweight custom syntax extensions, themselves defined using the
the pattern in the above code:
~~~~
# enum T { SpecialA(uint), SpecialB(uint) }
# fn f() -> uint {
# enum T { SpecialA(u32), SpecialB(u32) }
# fn f() -> u32 {
# let input_1 = T::SpecialA(0);
# let input_2 = T::SpecialA(0);
macro_rules! early_return {
@ -165,8 +165,8 @@ separator token (a comma-separated list could be written `$(...),*`), and `+`
instead of `*` to mean "at least one".
~~~~
# enum T { SpecialA(uint),SpecialB(uint),SpecialC(uint),SpecialD(uint)}
# fn f() -> uint {
# enum T { SpecialA(u32), SpecialB(u32), SpecialC(u32), SpecialD(u32) }
# fn f() -> u32 {
# let input_1 = T::SpecialA(0);
# let input_2 = T::SpecialA(0);
macro_rules! early_return {
@ -226,10 +226,10 @@ solves the problem.
Now consider code like the following:
~~~~
# enum T1 { Good1(T2, uint), Bad1}
# enum T1 { Good1(T2, u32), Bad1}
# struct T2 { body: T3 }
# enum T3 { Good2(uint), Bad2}
# fn f(x: T1) -> uint {
# enum T3 { Good2(u32), Bad2}
# fn f(x: T1) -> u32 {
match x {
T1::Good1(g1, val) => {
match g1.body {
@ -273,10 +273,10 @@ macro_rules! biased_match {
)
}
# enum T1 { Good1(T2, uint), Bad1}
# enum T1 { Good1(T2, u32), Bad1}
# struct T2 { body: T3 }
# enum T3 { Good2(uint), Bad2}
# fn f(x: T1) -> uint {
# enum T3 { Good2(u32), Bad2}
# fn f(x: T1) -> u32 {
biased_match!((x) -> (T1::Good1(g1, val)) else { return 0 };
binds g1, val );
biased_match!((g1.body) -> (T3::Good2(result) )
@ -383,10 +383,10 @@ macro_rules! biased_match {
}
# enum T1 { Good1(T2, uint), Bad1}
# enum T1 { Good1(T2, u32), Bad1}
# struct T2 { body: T3 }
# enum T3 { Good2(uint), Bad2}
# fn f(x: T1) -> uint {
# enum T3 { Good2(u32), Bad2}
# fn f(x: T1) -> u32 {
biased_match!(
(x) -> (T1::Good1(g1, val)) else { return 0 };
(g1.body) -> (T3::Good2(result) ) else { panic!("Didn't get Good2") };
@ -528,7 +528,7 @@ A further difficulty occurs when a macro is used in multiple crates. Say that
`mylib` defines
```rust
pub fn increment(x: uint) -> uint {
pub fn increment(x: u32) -> u32 {
x + 1
}

View File

@ -84,9 +84,9 @@ fn main() {
let y = 10;
match cmp(x, y) {
Ordering::Less => println!("less"),
Ordering::Less => println!("less"),
Ordering::Greater => println!("greater"),
Ordering::Equal => println!("equal"),
Ordering::Equal => println!("equal"),
}
}
```
@ -112,12 +112,12 @@ fn main() {
match x {
OptionalInt::Value(n) => println!("x is {}", n),
OptionalInt::Missing => println!("x is missing!"),
OptionalInt::Missing => println!("x is missing!"),
}
match y {
OptionalInt::Value(n) => println!("y is {}", n),
OptionalInt::Missing => println!("y is missing!"),
OptionalInt::Missing => println!("y is missing!"),
}
}
```
@ -146,9 +146,9 @@ fn main() {
let y = 10;
println!("{}", match cmp(x, y) {
Ordering::Less => "less",
Ordering::Less => "less",
Ordering::Greater => "greater",
Ordering::Equal => "equal",
Ordering::Equal => "equal",
});
}
```

View File

@ -1,4 +1,4 @@
% The Rust Ownership Guide
% Ownership
This guide presents Rust's ownership system. This is one of Rust's most unique
and compelling features, with which Rust developers should become quite
@ -418,7 +418,7 @@ struct Wheel {
fn main() {
let car = Car { name: "DeLorean".to_string() };
for _ in range(0u, 4) {
for _ in range(0, 4) {
Wheel { size: 360, owner: car };
}
}
@ -456,7 +456,7 @@ fn main() {
let car_owner = Rc::new(car);
for _ in range(0u, 4) {
for _ in range(0, 4) {
Wheel { size: 360, owner: car_owner.clone() };
}
}
@ -517,31 +517,31 @@ Here are some examples of functions with elided lifetimes, and the version of
what the elided lifetimes are expand to:
```{rust,ignore}
fn print(s: &str); // elided
fn print<'a>(s: &'a str); // expanded
fn print(s: &str); // elided
fn print<'a>(s: &'a str); // expanded
fn debug(lvl: u32, s: &str); // elided
fn debug<'a>(lvl: u32, s: &'a str); // expanded
fn debug(lvl: u32, s: &str); // elided
fn debug<'a>(lvl: u32, s: &'a str); // expanded
// In the preceeding example, `lvl` doesn't need a lifetime because it's not a
// reference (`&`). Only things relating to references (such as a `struct`
// which contains a reference) need lifetimes.
fn substr(s: &str, until: u32) -> &str; // elided
fn substr<'a>(s: &'a str, until: u32) -> &'a str; // expanded
fn substr(s: &str, until: u32) -> &str; // elided
fn substr<'a>(s: &'a str, until: u32) -> &'a str; // expanded
fn get_str() -> &str; // ILLEGAL, no inputs
fn get_str() -> &str; // ILLEGAL, no inputs
fn frob(s: &str, t: &str) -> &str; // ILLEGAL, two inputs
fn frob(s: &str, t: &str) -> &str; // ILLEGAL, two inputs
fn get_mut(&mut self) -> &mut T; // elided
fn get_mut<'a>(&'a mut self) -> &'a mut T; // expanded
fn get_mut(&mut self) -> &mut T; // elided
fn get_mut<'a>(&'a mut self) -> &'a mut T; // expanded
fn args<T:ToCStr>(&mut self, args: &[T]) -> &mut Command // elided
fn args<T:ToCStr>(&mut self, args: &[T]) -> &mut Command // elided
fn args<'a, 'b, T:ToCStr>(&'a mut self, args: &'b [T]) -> &'a mut Command // expanded
fn new(buf: &mut [u8]) -> BufWriter; // elided
fn new<'a>(buf: &'a mut [u8]) -> BufWriter<'a> // expanded
fn new(buf: &mut [u8]) -> BufWriter; // elided
fn new<'a>(buf: &'a mut [u8]) -> BufWriter<'a> // expanded
```
# Related Resources

View File

@ -8,7 +8,7 @@ A quick refresher: you can match against literals directly, and `_` acts as an
*any* case:
```{rust}
let x = 1i;
let x = 1;
match x {
1 => println!("one"),
@ -21,7 +21,7 @@ match x {
You can match multiple patterns with `|`:
```{rust}
let x = 1i;
let x = 1;
match x {
1 | 2 => println!("one or two"),
@ -33,7 +33,7 @@ match x {
You can match a range of values with `...`:
```{rust}
let x = 1i;
let x = 1;
match x {
1 ... 5 => println!("one through five"),
@ -47,7 +47,7 @@ If you're matching multiple things, via a `|` or a `...`, you can bind
the value to a name with `@`:
```{rust}
let x = 1i;
let x = 1;
match x {
e @ 1 ... 5 => println!("got a range element {}", e),
@ -60,15 +60,15 @@ ignore the value and type in the variant:
```{rust}
enum OptionalInt {
Value(int),
Value(i32),
Missing,
}
let x = OptionalInt::Value(5i);
let x = OptionalInt::Value(5);
match x {
OptionalInt::Value(..) => println!("Got an int!"),
OptionalInt::Missing => println!("No such luck."),
OptionalInt::Missing => println!("No such luck."),
}
```
@ -76,16 +76,16 @@ You can introduce *match guards* with `if`:
```{rust}
enum OptionalInt {
Value(int),
Value(i32),
Missing,
}
let x = OptionalInt::Value(5i);
let x = OptionalInt::Value(5);
match x {
OptionalInt::Value(i) if i > 5 => println!("Got an int bigger than five!"),
OptionalInt::Value(..) => println!("Got an int!"),
OptionalInt::Missing => println!("No such luck."),
OptionalInt::Missing => println!("No such luck."),
}
```
@ -93,33 +93,33 @@ If you're matching on a pointer, you can use the same syntax as you declared it
with. First, `&`:
```{rust}
let x = &5i;
let x = &5;
match x {
&val => println!("Got a value: {}", val),
}
```
Here, the `val` inside the `match` has type `int`. In other words, the left-hand
side of the pattern destructures the value. If we have `&5i`, then in `&val`, `val`
would be `5i`.
Here, the `val` inside the `match` has type `i32`. In other words, the left-hand
side of the pattern destructures the value. If we have `&5`, then in `&val`, `val`
would be `5`.
If you want to get a reference, use the `ref` keyword:
```{rust}
let x = 5i;
let x = 5;
match x {
ref r => println!("Got a reference to {}", r),
}
```
Here, the `r` inside the `match` has the type `&int`. In other words, the `ref`
Here, the `r` inside the `match` has the type `&i32`. In other words, the `ref`
keyword _creates_ a reference, for use in the pattern. If you need a mutable
reference, `ref mut` will work in the same way:
```{rust}
let mut x = 5i;
let mut x = 5;
match x {
ref mut mr => println!("Got a mutable reference to {}", mr),
@ -131,11 +131,11 @@ If you have a struct, you can destructure it inside of a pattern:
```{rust}
# #![allow(non_shorthand_field_patterns)]
struct Point {
x: int,
y: int,
x: i32,
y: i32,
}
let origin = Point { x: 0i, y: 0i };
let origin = Point { x: 0, y: 0 };
match origin {
Point { x: x, y: y } => println!("({},{})", x, y),
@ -147,11 +147,11 @@ If we only care about some of the values, we don't have to give them all names:
```{rust}
# #![allow(non_shorthand_field_patterns)]
struct Point {
x: int,
y: int,
x: i32,
y: i32,
}
let origin = Point { x: 0i, y: 0i };
let origin = Point { x: 0, y: 0 };
match origin {
Point { x: x, .. } => println!("x is {}", x),
@ -163,11 +163,11 @@ You can do this kind of match on any member, not just the first:
```{rust}
# #![allow(non_shorthand_field_patterns)]
struct Point {
x: int,
y: int,
x: i32,
y: i32,
}
let origin = Point { x: 0i, y: 0i };
let origin = Point { x: 0, y: 0 };
match origin {
Point { y: y, .. } => println!("y is {}", y),

View File

@ -1,4 +1,4 @@
% The Rust Compiler Plugins Guide
% Compiler Plugins
<div class="unstable-feature">
@ -68,7 +68,7 @@ use rustc::plugin::Registry;
fn expand_rn(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree])
-> Box<MacResult + 'static> {
static NUMERALS: &'static [(&'static str, uint)] = &[
static NUMERALS: &'static [(&'static str, u32)] = &[
("M", 1000), ("CM", 900), ("D", 500), ("CD", 400),
("C", 100), ("XC", 90), ("L", 50), ("XL", 40),
("X", 10), ("IX", 9), ("V", 5), ("IV", 4),
@ -83,7 +83,7 @@ fn expand_rn(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree])
};
let mut text = text.as_slice();
let mut total = 0u;
let mut total = 0;
while !text.is_empty() {
match NUMERALS.iter().find(|&&(rn, _)| text.starts_with(rn)) {
Some(&(rn, val)) => {
@ -118,7 +118,7 @@ fn main() {
}
```
The advantages over a simple `fn(&str) -> uint` are:
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.

View File

@ -1,4 +1,4 @@
% The Rust Pointer Guide
% Pointers
Rust's pointers are one of its more unique and compelling features. Pointers
are also one of the more confusing topics for newcomers to Rust. They can also
@ -28,9 +28,10 @@ question](http://stackoverflow.com/questions/79923/what-and-where-are-the-stack-
as the rest of this guide assumes you know the difference.) Like this:
```{rust}
let x = 5i;
let y = 8i;
let x = 5;
let y = 8;
```
| location | value |
|----------|-------|
| 0xd3e030 | 5 |
@ -46,10 +47,11 @@ Let's introduce a pointer. In some languages, there is just one type of
*reference*, which is the simplest kind of pointer.
```{rust}
let x = 5i;
let y = 8i;
let x = 5;
let y = 8;
let z = &y;
```
|location | value |
|-------- |----------|
|0xd3e030 | 5 |
@ -58,12 +60,12 @@ let z = &y;
See the difference? Rather than contain a value, the value of a pointer is a
location in memory. In this case, the location of `y`. `x` and `y` have the
type `int`, but `z` has the type `&int`. We can print this location using the
type `i32`, but `z` has the type `&i32`. We can print this location using the
`{:p}` format string:
```{rust}
let x = 5i;
let y = 8i;
let x = 5;
let y = 8;
let z = &y;
println!("{:p}", z);
@ -71,12 +73,12 @@ println!("{:p}", z);
This would print `0xd3e028`, with our fictional memory addresses.
Because `int` and `&int` are different types, we can't, for example, add them
Because `i32` and `&i32` are different types, we can't, for example, add them
together:
```{rust,ignore}
let x = 5i;
let y = 8i;
let x = 5;
let y = 8;
let z = &y;
println!("{}", x + z);
@ -85,7 +87,7 @@ println!("{}", x + z);
This gives us an error:
```text
hello.rs:6:24: 6:25 error: mismatched types: expected `int` but found `&int` (expected int but found &-ptr)
hello.rs:6:24: 6:25 error: mismatched types: expected `i32` but found `&i32` (expected i32 but found &-ptr)
hello.rs:6 println!("{}", x + z);
^
```
@ -95,8 +97,8 @@ pointer means accessing the value at the location stored in the pointer. This
will work:
```{rust}
let x = 5i;
let y = 8i;
let x = 5;
let y = 8;
let z = &y;
println!("{}", x + *z);
@ -153,7 +155,7 @@ So what do pointers have to do with this? Well, since pointers point to a
location in memory...
```text
func foo(&int x) {
func foo(&i32 x) {
*x = 5
}
@ -252,7 +254,7 @@ The most basic type of pointer that Rust has is called a *reference*. Rust
references look like this:
```{rust}
let x = 5i;
let x = 5;
let y = &x;
println!("{}", *y);
@ -269,18 +271,18 @@ referent, because `println!` will automatically dereference it for us.
Here's a function that takes a reference:
```{rust}
fn succ(x: &int) -> int { *x + 1 }
fn succ(x: &i32) -> i32 { *x + 1 }
```
You can also use `&` as an operator to create a reference, so we can
call this function in two different ways:
```{rust}
fn succ(x: &int) -> int { *x + 1 }
fn succ(x: &i32) -> i32 { *x + 1 }
fn main() {
let x = 5i;
let x = 5;
let y = &x;
println!("{}", succ(y));
@ -294,13 +296,13 @@ Of course, if this were real code, we wouldn't bother with the reference, and
just write:
```{rust}
fn succ(x: int) -> int { x + 1 }
fn succ(x: i32) -> i32 { x + 1 }
```
References are immutable by default:
```{rust,ignore}
let x = 5i;
let x = 5;
let y = &x;
*y = 5; // error: cannot assign to immutable dereference of `&`-pointer `*y`
@ -310,21 +312,21 @@ They can be made mutable with `mut`, but only if its referent is also mutable.
This works:
```{rust}
let mut x = 5i;
let mut x = 5;
let y = &mut x;
```
This does not:
```{rust,ignore}
let x = 5i;
let x = 5;
let y = &mut x; // error: cannot borrow immutable local variable `x` as mutable
```
Immutable pointers are allowed to alias:
```{rust}
let x = 5i;
let x = 5;
let y = &x;
let z = &x;
```
@ -332,7 +334,7 @@ let z = &x;
Mutable ones, however, are not:
```{rust,ignore}
let mut x = 5i;
let mut x = 5;
let y = &mut x;
let z = &mut x; // error: cannot borrow `x` as mutable more than once at a time
```
@ -359,7 +361,7 @@ duration a *lifetime*. Let's try a more complex example:
```{rust}
fn main() {
let x = &mut 5i;
let x = &mut 5;
if *x < 10 {
let y = &x;
@ -380,7 +382,7 @@ mutated, and therefore, lets us pass. This wouldn't work:
```{rust,ignore}
fn main() {
let x = &mut 5i;
let x = &mut 5;
if *x < 10 {
let y = &x;
@ -425,13 +427,13 @@ References just borrow ownership, which is more polite if you don't need the
ownership. In other words, prefer:
```{rust}
fn succ(x: &int) -> int { *x + 1 }
fn succ(x: &i32) -> i32 { *x + 1 }
```
to
```{rust}
fn succ(x: Box<int>) -> int { *x + 1 }
fn succ(x: Box<i32>) -> i32 { *x + 1 }
```
As a corollary to that rule, references allow you to accept a wide variety of
@ -439,7 +441,7 @@ other pointers, and so are useful so that you don't have to write a number
of variants per pointer. In other words, prefer:
```{rust}
fn succ(x: &int) -> int { *x + 1 }
fn succ(x: &i32) -> i32 { *x + 1 }
```
to
@ -447,9 +449,9 @@ to
```{rust}
use std::rc::Rc;
fn box_succ(x: Box<int>) -> int { *x + 1 }
fn box_succ(x: Box<i32>) -> i32 { *x + 1 }
fn rc_succ(x: Rc<int>) -> int { *x + 1 }
fn rc_succ(x: Rc<i32>) -> i32 { *x + 1 }
```
Note that the caller of your function will have to modify their calls slightly:
@ -457,11 +459,11 @@ Note that the caller of your function will have to modify their calls slightly:
```{rust}
use std::rc::Rc;
fn succ(x: &int) -> int { *x + 1 }
fn succ(x: &i32) -> i32 { *x + 1 }
let ref_x = &5i;
let box_x = Box::new(5i);
let rc_x = Rc::new(5i);
let ref_x = &5;
let box_x = Box::new(5);
let rc_x = Rc::new(5);
succ(ref_x);
succ(&*box_x);
@ -477,7 +479,7 @@ those contents.
heap allocation in Rust. Creating a box looks like this:
```{rust}
let x = Box::new(5i);
let x = Box::new(5);
```
Boxes are heap allocated and they are deallocated automatically by Rust when
@ -485,7 +487,7 @@ they go out of scope:
```{rust}
{
let x = Box::new(5i);
let x = Box::new(5);
// stuff happens
@ -505,7 +507,7 @@ boxes, though. As a rough approximation, you can treat this Rust code:
```{rust}
{
let x = Box::new(5i);
let x = Box::new(5);
// stuff happens
}
@ -544,12 +546,12 @@ for more detail on how lifetimes work.
Using boxes and references together is very common. For example:
```{rust}
fn add_one(x: &int) -> int {
fn add_one(x: &i32) -> i32 {
*x + 1
}
fn main() {
let x = Box::new(5i);
let x = Box::new(5);
println!("{}", add_one(&*x));
}
@ -561,12 +563,12 @@ function, and since it's only reading the value, allows it.
We can borrow `x` multiple times, as long as it's not simultaneous:
```{rust}
fn add_one(x: &int) -> int {
fn add_one(x: &i32) -> i32 {
*x + 1
}
fn main() {
let x = Box::new(5i);
let x = Box::new(5);
println!("{}", add_one(&*x));
println!("{}", add_one(&*x));
@ -577,12 +579,12 @@ fn main() {
Or as long as it's not a mutable borrow. This will error:
```{rust,ignore}
fn add_one(x: &mut int) -> int {
fn add_one(x: &mut i32) -> i32 {
*x + 1
}
fn main() {
let x = Box::new(5i);
let x = Box::new(5);
println!("{}", add_one(&*x)); // error: cannot borrow immutable dereference
// of `&`-pointer as mutable
@ -610,7 +612,7 @@ enum List<T> {
}
fn main() {
let list: List<int> = List::Cons(1, Box::new(List::Cons(2, Box::new(List::Cons(3, Box::new(List::Nil))))));
let list: List<i32> = List::Cons(1, Box::new(List::Cons(2, Box::new(List::Cons(3, Box::new(List::Nil))))));
println!("{:?}", list);
}
```
@ -659,10 +661,10 @@ so as to avoid copying a large data structure. For example:
```{rust}
struct BigStruct {
one: int,
two: int,
one: i32,
two: i32,
// etc
one_hundred: int,
one_hundred: i32,
}
fn foo(x: Box<BigStruct>) -> Box<BigStruct> {
@ -687,10 +689,10 @@ This is an antipattern in Rust. Instead, write this:
```{rust}
struct BigStruct {
one: int,
two: int,
one: i32,
two: i32,
// etc
one_hundred: int,
one_hundred: i32,
}
fn foo(x: Box<BigStruct>) -> BigStruct {

View File

@ -83,12 +83,12 @@ fn main() {
match x {
OptionalInt::Value(n) => println!("x is {}", n),
OptionalInt::Missing => println!("x is missing!"),
OptionalInt::Missing => println!("x is missing!"),
}
match y {
OptionalInt::Value(n) => println!("y is {}", n),
OptionalInt::Missing => println!("y is missing!"),
OptionalInt::Missing => println!("y is missing!"),
}
}
```
@ -141,11 +141,11 @@ use std::io;
fn main() {
println!("Type something!");
// here, we'll show the types at each step
// here, we'll show the types at each step
let input = io::stdin() // std::io::stdio::StdinReader
.read_line() // IoResult<String>
.ok() // Option<String>
let input = io::stdin() // std::io::stdio::StdinReader
.read_line() // IoResult<String>
.ok() // Option<String>
.expect("Failed to read line"); // String
println!("{}", input);

View File

@ -1,4 +1,4 @@
% The Rust Testing Guide
% Testing
> Program testing can be a very effective way to show the presence of bugs, but
> it is hopelessly inadequate for showing their absence.
@ -512,7 +512,7 @@ use test::Bencher;
#[bench]
fn bench_xor_1000_ints(b: &mut Bencher) {
b.iter(|| {
range(0u, 1000).fold(0, |old, new| old ^ new);
range(0, 1000).fold(0, |old, new| old ^ new);
});
}
```
@ -537,7 +537,7 @@ computation entirely. This could be done for the example above by adjusting the
# impl X { fn iter<T, F>(&self, _: F) where F: FnMut() -> T {} } let b = X;
b.iter(|| {
// note lack of `;` (could also use an explicit `return`).
range(0u, 1000).fold(0, |old, new| old ^ new)
range(0, 1000).fold(0, |old, new| old ^ new)
});
```

View File

@ -51,13 +51,15 @@ closure is limited to capturing `Send`-able data from its environment
ensures that `spawn` can safely move the entire closure and all its
associated state into an entirely different thread for execution.
```{rust,ignore}
# use std::thread::spawn;
# fn generate_thread_number() -> int { 0 }
```rust
use std::thread::Thread;
fn generate_thread_number() -> i32 { 4 } // a very simple generation
// Generate some state locally
let child_thread_number = generate_thread_number();
spawn(move || {
Thread::spawn(move || {
// Capture it in the remote thread. The `move` keyword indicates
// that this closure should move `child_thread_number` into its
// environment, rather than capturing a reference into the
@ -77,20 +79,22 @@ The simplest way to create a channel is to use the `channel` function to create
of a channel, and a *receiver* is the receiving endpoint. Consider the following
example of calculating two results concurrently:
```{rust,ignore}
# use std::thread::spawn;
```rust
use std::thread::Thread;
use std::sync::mpsc;
let (tx, rx): (Sender<int>, Receiver<int>) = channel();
let (tx, rx): (mpsc::Sender<u32>, mpsc::Receiver<u32>) = mpsc::channel();
spawn(move || {
Thread::spawn(move || {
let result = some_expensive_computation();
tx.send(result);
});
some_other_expensive_computation();
let result = rx.recv();
# fn some_expensive_computation() -> int { 42 }
# fn some_other_expensive_computation() {}
fn some_expensive_computation() -> u32 { 42 } // very expensive ;)
fn some_other_expensive_computation() {} // even more so
```
Let's examine this example in detail. First, the `let` statement creates a
@ -98,19 +102,21 @@ stream for sending and receiving integers (the left-hand side of the `let`,
`(tx, rx)`, is an example of a destructuring let: the pattern separates a tuple
into its component parts).
```{rust,ignore}
let (tx, rx): (Sender<int>, Receiver<int>) = channel();
```rust
# use std::sync::mpsc;
let (tx, rx): (mpsc::Sender<u32>, mpsc::Receiver<u32>) = mpsc::channel();
```
The child thread will use the sender to send data to the parent thread, which will
wait to receive the data on the receiver. The next statement spawns the child
thread.
```{rust,ignore}
# use std::thread::spawn;
# fn some_expensive_computation() -> int { 42 }
# let (tx, rx) = channel();
spawn(move || {
```rust
# use std::thread::Thread;
# use std::sync::mpsc;
# fn some_expensive_computation() -> u32 { 42 }
# let (tx, rx) = mpsc::channel();
Thread::spawn(move || {
let result = some_expensive_computation();
tx.send(result);
});
@ -125,9 +131,10 @@ computation, then sends the result over the captured channel.
Finally, the parent continues with some other expensive computation, then waits
for the child's result to arrive on the receiver:
```{rust,ignore}
```rust
# use std::sync::mpsc;
# fn some_other_expensive_computation() {}
# let (tx, rx) = channel::<int>();
# let (tx, rx) = mpsc::channel::<u32>();
# tx.send(0);
some_other_expensive_computation();
let result = rx.recv();
@ -140,8 +147,9 @@ single `Receiver` value. What if our example needed to compute multiple
results across a number of threads? The following program is ill-typed:
```{rust,ignore}
# fn some_expensive_computation() -> int { 42 }
let (tx, rx) = channel();
# use std::sync::mpsc;
# fn some_expensive_computation() -> u32 { 42 }
let (tx, rx) = mpsc::channel();
spawn(move || {
tx.send(some_expensive_computation());
@ -156,19 +164,22 @@ spawn(move || {
Instead we can clone the `tx`, which allows for multiple senders.
```{rust,ignore}
let (tx, rx) = channel();
```rust
use std::thread::Thread;
use std::sync::mpsc;
for init_val in range(0u, 3) {
let (tx, rx) = mpsc::channel();
for init_val in 0 .. 3 {
// Create a new channel handle to distribute to the child thread
let child_tx = tx.clone();
spawn(move || {
Thread::spawn(move || {
child_tx.send(some_expensive_computation(init_val));
});
}
let result = rx.recv() + rx.recv() + rx.recv();
# fn some_expensive_computation(_i: uint) -> int { 42 }
let result = rx.recv().unwrap() + rx.recv().unwrap() + rx.recv().unwrap();
# fn some_expensive_computation(_i: u32) -> u32 { 42 }
```
Cloning a `Sender` produces a new handle to the same channel, allowing multiple
@ -181,21 +192,22 @@ Note that the above cloning example is somewhat contrived since you could also
simply use three `Sender` pairs, but it serves to illustrate the point. For
reference, written with multiple streams, it might look like the example below.
```{rust,ignore}
# use std::thread::spawn;
```rust
use std::thread::Thread;
use std::sync::mpsc;
// Create a vector of ports, one for each child thread
let rxs = Vec::from_fn(3, |init_val| {
let (tx, rx) = channel();
spawn(move || {
let rxs = (0 .. 3).map(|&:init_val| {
let (tx, rx) = mpsc::channel();
Thread::spawn(move || {
tx.send(some_expensive_computation(init_val));
});
rx
});
}).collect::<Vec<_>>();
// Wait on each port, accumulating the results
let result = rxs.iter().fold(0, |accum, rx| accum + rx.recv() );
# fn some_expensive_computation(_i: uint) -> int { 42 }
let result = rxs.iter().fold(0, |&:accum, rx| accum + rx.recv().unwrap() );
# fn some_expensive_computation(_i: u32) -> u32 { 42 }
```
## Backgrounding computations: Futures
@ -212,7 +224,7 @@ use std::sync::Future;
# fn main() {
# fn make_a_sandwich() {};
fn fib(n: u64) -> u64 {
// lengthy computation returning an uint
// lengthy computation returning an 64
12586269025
}
@ -237,7 +249,7 @@ computations. The workload will be distributed on the available cores.
# #![allow(deprecated)]
# use std::num::Float;
# use std::sync::Future;
fn partial_sum(start: uint) -> f64 {
fn partial_sum(start: u64) -> f64 {
let mut local_sum = 0f64;
for num in range(start*100000, (start+1)*100000) {
local_sum += (num as f64 + 1.0).powf(-2.0);
@ -277,7 +289,7 @@ use std::num::Float;
use std::rand;
use std::sync::Arc;
fn pnorm(nums: &[f64], p: uint) -> f64 {
fn pnorm(nums: &[f64], p: u64) -> f64 {
nums.iter().fold(0.0, |a, b| a + b.powf(p as f64)).powf(1.0 / (p as f64))
}
@ -285,7 +297,7 @@ fn main() {
let numbers = Vec::from_fn(1000000, |_| rand::random::<f64>());
let numbers_arc = Arc::new(numbers);
for num in range(1u, 10) {
for num in range(1, 10) {
let thread_numbers = numbers_arc.clone();
spawn(move || {
@ -316,7 +328,7 @@ if it were local.
```{rust,ignore}
# use std::rand;
# use std::sync::Arc;
# fn pnorm(nums: &[f64], p: uint) -> f64 { 4.0 }
# fn pnorm(nums: &[f64], p: u64) -> f64 { 4.0 }
# fn main() {
# let numbers=Vec::from_fn(1000000, |_| rand::random::<f64>());
# let numbers_arc = Arc::new(numbers);
@ -345,16 +357,16 @@ each other if they panic. The simplest way of handling a panic is with the
`try` function, which is similar to `spawn`, but immediately blocks and waits
for the child thread to finish. `try` returns a value of type
`Result<T, Box<Any + Send>>`. `Result` is an `enum` type with two variants:
`Ok` and `Err`. In this case, because the type arguments to `Result` are `int`
`Ok` and `Err`. In this case, because the type arguments to `Result` are `i32`
and `()`, callers can pattern-match on a result to check whether it's an `Ok`
result with an `int` field (representing a successful result) or an `Err` result
result with an `i32` field (representing a successful result) or an `Err` result
(representing termination with an error).
```{rust,ignore}
# use std::thread::Thread;
# fn some_condition() -> bool { false }
# fn calculate_result() -> int { 0 }
let result: Result<int, Box<std::any::Any + Send>> = Thread::spawn(move || {
# fn calculate_result() -> i32 { 0 }
let result: Result<i32, Box<std::any::Any + Send>> = Thread::spawn(move || {
if some_condition() {
calculate_result()
} else {

View File

@ -145,7 +145,7 @@ As you can see, `print_area` is now generic, but also ensures that we
have passed in the correct types. If we pass in an incorrect type:
```{rust,ignore}
print_area(5i);
print_area(5);
```
We get a compile-time error:
@ -156,14 +156,14 @@ error: failed to find an implementation of trait main::HasArea for int
So far, we've only added trait implementations to structs, but you can
implement a trait for any type. So technically, we _could_ implement
`HasArea` for `int`:
`HasArea` for `i32`:
```{rust}
trait HasArea {
fn area(&self) -> f64;
}
impl HasArea for int {
impl HasArea for i32 {
fn area(&self) -> f64 {
println!("this is silly");
@ -171,7 +171,7 @@ impl HasArea for int {
}
}
5i.area();
5.area();
```
It is considered poor style to implement methods on such primitive types, even
@ -264,8 +264,8 @@ it won't affect you, unless you `use` that trait.
There's one more restriction on implementing traits. Either the trait or the
type you're writing the `impl` for must be inside your crate. So, we could
implement the `HasArea` type for `int`, because `HasArea` is in our crate. But
if we tried to implement `Float`, a trait provided by Rust, for `int`, we could
implement the `HasArea` type for `i32`, because `HasArea` is in our crate. But
if we tried to implement `Float`, a trait provided by Rust, for `i32`, we could
not, because both the trait and the type aren't in our crate.
One last thing about traits: generic functions with a trait bound use

View File

@ -1,4 +1,4 @@
% Writing Unsafe and Low-Level Code in Rust
% Unsafe and Low-Level Code
# Introduction
@ -95,7 +95,7 @@ offered by the Rust language and libraries. For example, they
use-after-free;
- are considered sendable (if their contents is considered sendable),
so the compiler offers no assistance with ensuring their use is
thread-safe; for example, one can concurrently access a `*mut int`
thread-safe; for example, one can concurrently access a `*mut i32`
from two threads without synchronization.
- lack any form of lifetimes, unlike `&`, and so the compiler cannot
reason about dangling pointers; and
@ -265,12 +265,12 @@ impl<T: Send> Drop for Unique<T> {
// A comparison between the built-in `Box` and this reimplementation
fn main() {
{
let mut x = Box::new(5i);
let mut x = Box::new(5);
*x = 10;
} // `x` is freed here
{
let mut y = Unique::new(5i);
let mut y = Unique::new(5);
*y.borrow_mut() = 10;
} // `y` is freed here
}
@ -367,7 +367,7 @@ expressions must be mutable lvalues:
```
# #![feature(asm)]
# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
fn add(a: int, b: int) -> int {
fn add(a: i32, b: i32) -> i32 {
let mut c = 0;
unsafe {
asm!("add $2, $0"
@ -378,7 +378,7 @@ fn add(a: int, b: int) -> int {
c
}
# #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
# fn add(a: int, b: int) -> int { a + b }
# fn add(a: i32, b: i32) -> i32 { a + b }
fn main() {
assert_eq!(add(3, 14159), 14162)
@ -454,7 +454,7 @@ extern crate libc;
// Entry point for this program
#[start]
fn start(_argc: int, _argv: *const *const u8) -> int {
fn start(_argc: isize, _argv: *const *const u8) -> isize {
0
}
@ -480,7 +480,7 @@ compiler's name mangling too:
extern crate libc;
#[no_mangle] // ensure that this symbol is called `main` in the output
pub extern fn main(argc: int, argv: *const *const u8) -> int {
pub extern fn main(argc: i32, argv: *const *const u8) -> i32 {
0
}
@ -552,8 +552,8 @@ pub extern fn dot_product(a: *const u32, a_len: u32,
// cannot tell the pointers are valid.
let (a_slice, b_slice): (&[u32], &[u32]) = unsafe {
mem::transmute((
Slice { data: a, len: a_len as uint },
Slice { data: b, len: b_len as uint },
Slice { data: a, len: a_len as usize },
Slice { data: b, len: b_len as usize },
))
};
@ -567,14 +567,14 @@ pub extern fn dot_product(a: *const u32, a_len: u32,
#[lang = "panic_fmt"]
extern fn panic_fmt(args: &core::fmt::Arguments,
file: &str,
line: uint) -> ! {
file: &str,
line: u32) -> ! {
loop {}
}
#[lang = "stack_exhausted"] extern fn stack_exhausted() {}
#[lang = "eh_personality"] extern fn eh_personality() {}
# #[start] fn start(argc: int, argv: *const *const u8) -> int { 0 }
# #[start] fn start(argc: isize, argv: *const *const u8) -> isize { 0 }
# fn main() {}
```
@ -628,7 +628,7 @@ via a declaration like
extern "rust-intrinsic" {
fn transmute<T, U>(x: T) -> U;
fn offset<T>(dst: *const T, offset: int) -> *const T;
fn offset<T>(dst: *const T, offset: isize) -> *const T;
}
```
@ -665,24 +665,24 @@ extern {
pub struct Box<T>(*mut T);
#[lang="exchange_malloc"]
unsafe fn allocate(size: uint, _align: uint) -> *mut u8 {
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 uint == 0 {
if p as usize == 0 {
abort();
}
p
}
#[lang="exchange_free"]
unsafe fn deallocate(ptr: *mut u8, _size: uint, _align: uint) {
unsafe fn deallocate(ptr: *mut u8, _size: usize, _align: usize) {
libc::free(ptr as *mut libc::c_void)
}
#[start]
fn main(argc: int, argv: *const *const u8) -> int {
let x = box 1i;
fn main(argc: isize, argv: *const *const u8) -> isize {
let x = box 1;
0
}

View File

@ -1,4 +1,4 @@
% Variable bindings
% Variable Bindings
The first thing we'll learn about are *variable bindings*. They look like this:

View File

@ -156,7 +156,7 @@ static FALSE: bool = false;
/// println!("{:?}", bv);
/// println!("total bits set to true: {}", bv.iter().filter(|x| *x).count());
/// ```
#[stable]
#[unstable = "RFC 509"]
pub struct Bitv {
/// Internal representation of the bit vector
storage: Vec<u32>,
@ -1107,7 +1107,7 @@ impl<'a> RandomAccessIterator for Iter<'a> {
/// assert!(bv[3]);
/// ```
#[derive(Clone)]
#[stable]
#[unstable = "RFC 509"]
pub struct BitvSet {
bitv: Bitv,
}

View File

@ -70,12 +70,12 @@ pub mod string;
pub mod vec;
pub mod vec_map;
#[stable]
#[unstable = "RFC 509"]
pub mod bitv {
pub use bit::{Bitv, Iter};
}
#[stable]
#[unstable = "RFC 509"]
pub mod bitv_set {
pub use bit::{BitvSet, Union, Intersection, Difference, SymmetricDifference};
pub use bit::SetIter as Iter;

View File

@ -115,7 +115,6 @@
//! }
//! # fn calc_span_tree(&self) -> Vec<(uint, uint)> { vec![] }
//! }
//! # fn main() { }
//! ```
//!
//! ## Mutating implementations of `clone`

View File

@ -23,13 +23,11 @@
//!
//! use std::finally::Finally;
//!
//! # fn main() {
//! (|&mut:| {
//! // ...
//! }).finally(|| {
//! // this code is always run
//! })
//! # }
//! ```
#![deprecated = "It is unclear if this module is more robust than implementing \

View File

@ -39,13 +39,16 @@ macro_rules! panic {
/// // the panic message for these assertions is the stringified value of the
/// // expression given.
/// assert!(true);
/// # fn some_computation() -> bool { true }
///
/// fn some_computation() -> bool { true } // a very simple function
///
/// assert!(some_computation());
///
/// // assert with a custom message
/// # let x = true;
/// let x = true;
/// assert!(x, "x wasn't true!");
/// # let a = 3i; let b = 27i;
///
/// let a = 3i; let b = 27i;
/// assert!(a + b == 30, "a = {}, b = {}", a, b);
/// ```
#[macro_export]
@ -108,13 +111,15 @@ macro_rules! assert_eq {
/// // the panic message for these assertions is the stringified value of the
/// // expression given.
/// debug_assert!(true);
/// # fn some_expensive_computation() -> bool { true }
///
/// fn some_expensive_computation() -> bool { true } // a very simple function
/// debug_assert!(some_expensive_computation());
///
/// // assert with a custom message
/// # let x = true;
/// let x = true;
/// debug_assert!(x, "x wasn't true!");
/// # let a = 3i; let b = 27i;
///
/// let a = 3; let b = 27;
/// debug_assert!(a + b == 30, "a = {}, b = {}", a, b);
/// ```
#[macro_export]

View File

@ -42,6 +42,104 @@ pub trait Sized {
}
/// Types that can be copied by simply copying bits (i.e. `memcpy`).
///
/// By default, variable bindings have 'move semantics.' In other
/// words:
///
/// ```
/// #[derive(Show)]
/// struct Foo;
///
/// let x = Foo;
///
/// let y = x;
///
/// // `x` has moved into `y`, and so cannot be used
///
/// // println!("{:?}", x); // error: use of moved value
/// ```
///
/// However, if a type implements `Copy`, it instead has 'copy semantics':
///
/// ```
/// // we can just derive a `Copy` implementation
/// #[derive(Show, Copy)]
/// struct Foo;
///
/// let x = Foo;
///
/// let y = x;
///
/// // `y` is a copy of `x`
///
/// println!("{:?}", x); // A-OK!
/// ```
///
/// It's important to note that in these two examples, the only difference is if you are allowed to
/// access `x` after the assignment: a move is also a bitwise copy under the hood.
///
/// ## When can my type be `Copy`?
///
/// A type can implement `Copy` if all of its components implement `Copy`. For example, this
/// `struct` can be `Copy`:
///
/// ```
/// struct Point {
/// x: i32,
/// y: i32,
/// }
/// ```
///
/// A `struct` can be `Copy`, and `i32` is `Copy`, so therefore, `Point` is eligible to be `Copy`.
///
/// ```
/// # struct Point;
/// struct PointList {
/// points: Vec<Point>,
/// }
/// ```
///
/// The `PointList` `struct` cannot implement `Copy`, because `Vec<T>` is not `Copy`. If we
/// attempt to derive a `Copy` implementation, we'll get an error.
///
/// ```text
/// error: the trait `Copy` may not be implemented for this type; field `points` does not implement
/// `Copy`
/// ```
///
/// ## How can I implement `Copy`?
///
/// There are two ways to implement `Copy` on your type:
///
/// ```
/// #[derive(Copy)]
/// struct MyStruct;
/// ```
///
/// and
///
/// ```
/// struct MyStruct;
/// impl Copy for MyStruct {}
/// ```
///
/// There is a small difference between the two: the `derive` strategy will also place a `Copy`
/// bound on type parameters, which isn't always desired.
///
/// ## When can my type _not_ be `Copy`?
///
/// Some types can't be copied safely. For example, copying `&mut T` would create an aliased
/// mutable reference, and copying `String` would result in two attempts to free the same buffer.
///
/// Generalizing the latter case, any type implementing `Drop` can't be `Copy`, because it's
/// managing some resource besides its own `size_of::<T>()` bytes.
///
/// ## When should my type be `Copy`?
///
/// Generally speaking, if your type _can_ implement `Copy`, it should. There's one important thing
/// to consider though: if you think your type may _not_ be able to implement `Copy` in the future,
/// then it might be prudent to not implement `Copy`. This is because removing `Copy` is a breaking
/// change: that second example would fail to compile if we made `Foo` non-`Copy`.
#[stable]
#[lang="copy"]
pub trait Copy {
@ -210,8 +308,7 @@ impl<T: ?Sized> Clone for ContravariantType<T> {
/// "interior" mutability:
///
/// ```
/// pub struct Cell<T> { value: T }
/// # fn main() {}
/// struct Cell<T> { value: T }
/// ```
///
/// The type system would infer that `value` is only read here and

View File

@ -830,28 +830,27 @@ shr_impl_all! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize }
///
/// # Example
///
/// A trivial implementation of `Index`. When `Foo[Foo]` happens, it ends up
/// A trivial implementation of `Index`. When `Foo[Bar]` happens, it ends up
/// calling `index`, and therefore, `main` prints `Indexing!`.
///
/// ```
/// #![feature(associated_types)]
///
/// use std::ops::Index;
///
/// #[derive(Copy)]
/// struct Foo;
/// struct Bar;
///
/// impl Index<Foo> for Foo {
/// impl Index<Bar> for Foo {
/// type Output = Foo;
///
/// fn index<'a>(&'a self, _index: &Foo) -> &'a Foo {
/// fn index<'a>(&'a self, _index: &Bar) -> &'a Foo {
/// println!("Indexing!");
/// self
/// }
/// }
///
/// fn main() {
/// Foo[Foo];
/// Foo[Bar];
/// }
/// ```
#[lang="index"]
@ -867,28 +866,27 @@ pub trait Index<Index: ?Sized> {
///
/// # Example
///
/// A trivial implementation of `IndexMut`. When `Foo[Foo]` happens, it ends up
/// A trivial implementation of `IndexMut`. When `Foo[Bar]` happens, it ends up
/// calling `index_mut`, and therefore, `main` prints `Indexing!`.
///
/// ```
/// #![feature(associated_types)]
///
/// use std::ops::IndexMut;
///
/// #[derive(Copy)]
/// struct Foo;
/// struct Bar;
///
/// impl IndexMut<Foo> for Foo {
/// impl IndexMut<Bar> for Foo {
/// type Output = Foo;
///
/// fn index_mut<'a>(&'a mut self, _index: &Foo) -> &'a mut Foo {
/// fn index_mut<'a>(&'a mut self, _index: &Bar) -> &'a mut Foo {
/// println!("Indexing!");
/// self
/// }
/// }
///
/// fn main() {
/// &mut Foo[Foo];
/// &mut Foo[Bar];
/// }
/// ```
#[lang="index_mut"]

View File

@ -21,11 +21,7 @@
//! # Example
//!
//! ```ignore
//! # fn main() {
//! #![feature(globs)]
//!
//! use core::prelude::*;
//! # }
//! ```
// Reexported core operators

View File

@ -217,11 +217,9 @@
//! makes it clear:
//!
//! ```
//! # #![feature(macro_rules)]
//! macro_rules! try {
//! ($e:expr) => (match $e { Ok(e) => e, Err(e) => return Err(e) })
//! }
//! # fn main() { }
//! ```
//!
//! `try!` is imported by the prelude, and is available everywhere.

View File

@ -4168,6 +4168,27 @@ pub mod funcs {
pub fn malloc(size: size_t) -> *mut c_void;
pub fn realloc(p: *mut c_void, size: size_t) -> *mut c_void;
pub fn free(p: *mut c_void);
/// Exits the running program in a possibly dangerous manner.
///
/// # Unsafety
///
/// While this forces your program to exit, it does so in a way that has
/// consequences. This will skip all unwinding code, which means that anything
/// relying on unwinding for cleanup (such as flushing and closing a buffer to a
/// file) may act in an unexpected way.
///
/// # Examples
///
/// ```no_run
/// extern crate libc;
///
/// fn main() {
/// unsafe {
/// libc::exit(1);
/// }
/// }
/// ```
pub fn exit(status: c_int) -> !;
pub fn _exit(status: c_int) -> !;
pub fn atexit(cb: extern fn()) -> c_int;

View File

@ -44,6 +44,7 @@ extern crate rbml;
extern crate collections;
#[macro_use] extern crate log;
#[macro_use] extern crate syntax;
#[macro_use] #[no_link] extern crate rustc_bitflags;
extern crate "serialize" as rustc_serialize; // used by deriving

View File

@ -8,10 +8,16 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![crate_name = "rustc_bitflags"]
#![unstable]
#![staged_api]
#![crate_type = "rlib"]
#![no_std]
//! A typesafe bitmask flag generator.
#[cfg(test)] #[macro_use] extern crate std;
/// The `bitflags!` macro generates a `struct` that holds a set of C-style
/// bitmask flags. It is useful for creating typesafe wrappers for C APIs.
///
@ -21,6 +27,8 @@
/// # Example
///
/// ```{.rust}
/// #[macro_use] extern crate rustc_bitflags;
///
/// bitflags! {
/// flags Flags: u32 {
/// const FLAG_A = 0b00000001,
@ -45,6 +53,8 @@
/// The generated `struct`s can also be extended with type and trait implementations:
///
/// ```{.rust}
/// #[macro_use] extern crate rustc_bitflags;
///
/// use std::fmt;
///
/// bitflags! {
@ -273,8 +283,8 @@ macro_rules! bitflags {
#[cfg(test)]
#[allow(non_upper_case_globals)]
mod tests {
use hash::{self, SipHasher};
use option::Option::{Some, None};
use std::hash::{self, SipHasher};
use std::option::Option::{Some, None};
bitflags! {
#[doc = "> The first principle is that you must not fool yourself — and"]

View File

@ -28,6 +28,7 @@
#![allow(unknown_features)] #![feature(int_uint)]
extern crate libc;
#[macro_use] #[no_link] extern crate rustc_bitflags;
pub use self::OtherAttribute::*;
pub use self::SpecialAttribute::*;

View File

@ -23,6 +23,7 @@
#[macro_use] extern crate log;
#[macro_use] extern crate syntax;
#[macro_use] #[no_link] extern crate rustc_bitflags;
extern crate rustc;

View File

@ -26,15 +26,13 @@
//!
//! Some examples of the `format!` extension are:
//!
//! ```rust
//! # fn main() {
//! ```
//! format!("Hello"); // => "Hello"
//! format!("Hello, {}!", "world"); // => "Hello, world!"
//! format!("The number is {}", 1i); // => "The number is 1"
//! format!("{:?}", (3i, 4i)); // => "(3i, 4i)"
//! format!("{value}", value=4i); // => "4"
//! format!("{} {}", 1i, 2u); // => "1 2"
//! # }
//! ```
//!
//! From these, you can see that the first argument is a format string. It is
@ -83,12 +81,10 @@
//!
//! For example, the following `format!` expressions all use named argument:
//!
//! ```rust
//! # fn main() {
//! ```
//! format!("{argument}", argument = "test"); // => "test"
//! format!("{name} {}", 1i, name = 2i); // => "2 1"
//! format!("{a} {c} {b}", a="a", b='b', c=3i); // => "a 3 b"
//! # }
//! ```
//!
//! It is illegal to put positional parameters (those without names) after
@ -288,8 +284,6 @@
//! use std::fmt;
//! use std::io;
//!
//! # #[allow(unused_must_use)]
//! # fn main() {
//! fmt::format(format_args!("this returns {}", "String"));
//!
//! let some_writer: &mut io::Writer = &mut io::stdout();
@ -299,7 +293,6 @@
//! write!(&mut io::stdout(), "{}", args);
//! }
//! my_fmt_fn(format_args!("or a {} too", "function"));
//! # }
//! ```
//!
//! The result of the `format_args!` macro is a value of type `fmt::Arguments`.

View File

@ -934,16 +934,15 @@ unsafe fn slice_vec_capacity<'a, T>(v: &'a mut Vec<T>, start: uint, end: uint) -
/// A `RefReader` is a struct implementing `Reader` which contains a reference
/// to another reader. This is often useful when composing streams.
///
/// # Example
/// # Examples
///
/// ```
/// # fn main() {}
/// # fn process_input<R: Reader>(r: R) {}
/// # fn foo() {
/// use std::io;
/// use std::io::ByRefReader;
/// use std::io::util::LimitReader;
///
/// fn process_input<R: Reader>(r: R) {}
///
/// let mut stream = io::stdin();
///
/// // Only allow the function to process at most one kilobyte of input
@ -953,8 +952,6 @@ unsafe fn slice_vec_capacity<'a, T>(v: &'a mut Vec<T>, start: uint, end: uint) -
/// }
///
/// // 'stream' is still available for use here
///
/// # }
/// ```
pub struct RefReader<'a, R:'a> {
/// The underlying reader which this is referencing
@ -1269,12 +1266,11 @@ impl<'a> Writer for &'a mut (Writer+'a) {
/// # Example
///
/// ```
/// # fn main() {}
/// # fn process_input<R: Reader>(r: R) {}
/// # fn foo () {
/// use std::io::util::TeeReader;
/// use std::io::{stdin, ByRefWriter};
///
/// fn process_input<R: Reader>(r: R) {}
///
/// let mut output = Vec::new();
///
/// {
@ -1285,7 +1281,6 @@ impl<'a> Writer for &'a mut (Writer+'a) {
/// }
///
/// println!("input processed: {:?}", output);
/// # }
/// ```
pub struct RefWriter<'a, W:'a> {
/// The underlying writer which this is referencing
@ -1705,19 +1700,19 @@ pub enum FileType {
/// A structure used to describe metadata information about a file. This
/// structure is created through the `stat` method on a `Path`.
///
/// # Example
/// # Examples
///
/// ```no_run
/// # #![allow(unstable)]
///
/// use std::io::fs::PathExtensions;
///
/// ```
/// # use std::io::fs::PathExtensions;
/// # fn main() {}
/// # fn foo() {
/// let info = match Path::new("foo.txt").stat() {
/// Ok(stat) => stat,
/// Err(e) => panic!("couldn't read foo.txt: {}", e),
/// };
///
/// println!("byte size: {}", info.size);
/// # }
/// ```
#[derive(Copy, Hash)]
pub struct FileStat {

View File

@ -168,9 +168,7 @@ impl UnixListener {
/// # Example
///
/// ```
/// # fn main() {}
/// # fn foo() {
/// # #![allow(unused_must_use)]
/// use std::io::net::pipe::UnixListener;
/// use std::io::{Listener, Acceptor};
///

View File

@ -272,12 +272,10 @@ impl sys_common::AsInner<TcpStreamImp> for TcpStream {
/// A structure representing a socket server. This listener is used to create a
/// `TcpAcceptor` which can be used to accept sockets on a local port.
///
/// # Example
/// # Examples
///
/// ```rust
/// # fn main() { }
/// ```
/// # fn foo() {
/// # #![allow(dead_code)]
/// use std::io::{TcpListener, TcpStream};
/// use std::io::{Acceptor, Listener};
/// use std::thread::Thread;

View File

@ -27,10 +27,9 @@ use sys::timer::Timer as TimerImp;
/// period of time. Handles to this timer can also be created in the form of
/// receivers which will receive notifications over time.
///
/// # Example
/// # Examples
///
/// ```
/// # fn main() {}
/// # fn foo() {
/// use std::io::Timer;
/// use std::time::Duration;
@ -54,7 +53,6 @@ use sys::timer::Timer as TimerImp;
/// the `io::timer` module.
///
/// ```
/// # fn main() {}
/// # fn foo() {
/// use std::io::timer;
/// use std::time::Duration;

View File

@ -111,7 +111,7 @@
#![feature(box_syntax)]
#![feature(old_impl_check)]
#![feature(optin_builtin_traits)]
#![allow(unknown_features)] #![feature(int_uint)]
#![feature(int_uint)]
// Don't link to std. We are std.
#![no_std]
@ -136,6 +136,8 @@ extern crate alloc;
extern crate unicode;
extern crate libc;
#[macro_use] #[no_link] extern crate rustc_bitflags;
// Make std testable by not duplicating lang items. See #2912
#[cfg(test)] extern crate "std" as realstd;
#[cfg(test)] pub use realstd::marker;
@ -181,9 +183,6 @@ pub use unicode::char;
#[macro_use]
mod macros;
#[macro_use]
pub mod bitflags;
mod rtdeps;
/* The Prelude. */

View File

@ -122,16 +122,18 @@ macro_rules! try {
/// receivers. It places no restrictions on the types of receivers given to
/// this macro, this can be viewed as a heterogeneous select.
///
/// # Example
/// # Examples
///
/// ```
/// use std::thread::Thread;
/// use std::sync::mpsc::channel;
/// use std::sync::mpsc;
///
/// let (tx1, rx1) = channel();
/// let (tx2, rx2) = channel();
/// # fn long_running_task() {}
/// # fn calculate_the_answer() -> int { 42i }
/// // two placeholder functions for now
/// fn long_running_task() {}
/// fn calculate_the_answer() -> u32 { 42 }
///
/// let (tx1, rx1) = mpsc::channel();
/// let (tx2, rx2) = mpsc::channel();
///
/// Thread::spawn(move|| { long_running_task(); tx1.send(()).unwrap(); });
/// Thread::spawn(move|| { tx2.send(calculate_the_answer()).unwrap(); });
@ -251,13 +253,13 @@ pub mod builtin {
/// statement or expression position, meaning this macro may be difficult to
/// use in some situations.
///
/// # Example
/// # Examples
///
/// ```
/// #![feature(concat_idents)]
///
/// # fn main() {
/// fn foobar() -> int { 23 }
/// fn foobar() -> u32 { 23 }
///
/// let f = concat_idents!(foo, bar);
/// println!("{}", f());

View File

@ -11,14 +11,18 @@
//! A type representing values that may be computed concurrently and operations
//! for working with them.
//!
//! # Example
//! # Examples
//!
//! ```rust
//! ```
//! use std::sync::Future;
//! # fn fib(n: uint) -> uint {42};
//! # fn make_a_sandwich() {};
//! let mut delayed_fib = Future::spawn(move|| { fib(5000) });
//! make_a_sandwich();
//!
//! // a fake, for now
//! fn fib(n: u32) -> u32 { 42 };
//!
//! let mut delayed_fib = Future::spawn(move || fib(5000));
//!
//! // do stuff...
//!
//! println!("fib(5000) = {}", delayed_fib.get())
//! ```

View File

@ -35,6 +35,7 @@ extern crate serialize;
extern crate term;
extern crate libc;
#[macro_use] extern crate log;
#[macro_use] #[no_link] extern crate rustc_bitflags;
extern crate "serialize" as rustc_serialize; // used by deriving

View File

@ -14,5 +14,5 @@
extern crate libc;
fn main() {
println!("{}", 1.0 as *libc::FILE); // Can't cast float to foreign.
println!("{:?}", 1.0 as *const libc::FILE); // Can't cast float to foreign.
}