diff --git a/LICENSE-MIT b/LICENSE-MIT index 39d4bdb5acd..e69282e381b 100644 --- a/LICENSE-MIT +++ b/LICENSE-MIT @@ -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 diff --git a/mk/crates.mk b/mk/crates.mk index d6cc3598bd5..5957405f0f9 100644 --- a/mk/crates.mk +++ b/mk/crates.mk @@ -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 diff --git a/src/doc/intro.md b/src/doc/intro.md index d93b680ae6d..3487738467f 100644 --- a/src/doc/intro.md +++ b/src/doc/intro.md @@ -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); diff --git a/src/doc/reference.md b/src/doc/reference.md index c8e31f27b35..a27d6c6e268 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -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} diff --git a/src/doc/trpl/arrays-vectors-and-slices.md b/src/doc/trpl/arrays-vectors-and-slices.md index e7ac55bfbd3..2df769b3c2c 100644 --- a/src/doc/trpl/arrays-vectors-and-slices.md +++ b/src/doc/trpl/arrays-vectors-and-slices.md @@ -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 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 } ``` diff --git a/src/doc/trpl/compound-data-types.md b/src/doc/trpl/compound-data-types.md index 5ad9fcd41f5..0616f094e37 100644 --- a/src/doc/trpl/compound-data-types.md +++ b/src/doc/trpl/compound-data-types.md @@ -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. diff --git a/src/doc/trpl/crates-and-modules.md b/src/doc/trpl/crates-and-modules.md index c12090e2a61..6c5c14fe311 100644 --- a/src/doc/trpl/crates-and-modules.md +++ b/src/doc/trpl/crates-and-modules.md @@ -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 diff --git a/src/doc/trpl/error-handling.md b/src/doc/trpl/error-handling.md index 4b1c92239ae..d66142edf3f 100644 --- a/src/doc/trpl/error-handling.md +++ b/src/doc/trpl/error-handling.md @@ -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!() } } diff --git a/src/doc/trpl/ffi.md b/src/doc/trpl/ffi.md index 940d2c968be..640f9cc388e 100644 --- a/src/doc/trpl/ffi.md +++ b/src/doc/trpl/ffi.md @@ -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 { 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> { 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 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. + diff --git a/src/doc/trpl/functions.md b/src/doc/trpl/functions.md index eae7fc19895..d0ecb606795 100644 --- a/src/doc/trpl/functions.md +++ b/src/doc/trpl/functions.md @@ -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: diff --git a/src/doc/trpl/generics.md b/src/doc/trpl/generics.md index 023143ae64e..74cb4530935 100644 --- a/src/doc/trpl/generics.md +++ b/src/doc/trpl/generics.md @@ -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`, with some extra type annotations: ```{rust} -let x: Option = Some(5i); +let x: Option = Some(5); ``` -In the type declaration, we say `Option`. Note how similar this looks to -`Option`. 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`. Note how similar this looks to +`Option`. 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 = Some(5i); -// error: mismatched types: expected `core::option::Option` -// but found `core::option::Option` (expected f64 but found int) +let x: Option = Some(5); +// error: mismatched types: expected `core::option::Option`, +// found `core::option::Option<_>` (expected f64 but found integral variable) ``` That doesn't mean we can't make `Option`s that hold an `f64`! They just have to match up: ```{rust} -let x: Option = Some(5i); +let x: Option = Some(5); let y: Option = Some(5.0f64); ``` diff --git a/src/doc/trpl/guessing-game.md b/src/doc/trpl/guessing-game.md index 474e7db6942..6f67c88f2c0 100644 --- a/src/doc/trpl/guessing-game.md +++ b/src/doc/trpl/guessing-game.md @@ -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::(); // input_num: Option -let input_num: Option = "5".parse(); // input_num: Option +let input_num = "5".parse::(); // input_num: Option +let input_num: Option = "5".parse(); // input_num: Option ``` 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; }, diff --git a/src/doc/trpl/iterators.md b/src/doc/trpl/iterators.md index 8312f762c11..75b3f8b06fc 100644 --- a/src/doc/trpl/iterators.md +++ b/src/doc/trpl/iterators.md @@ -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`, 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`, 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::>(); +let one_to_one_hundred = range(1, 101).collect::>(); ``` 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::>(); +let nums = range(1, 100).collect::>(); ``` 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::>(); + .collect::>(); ``` This will give you a vector containing `6`, `12`, `18`, `24`, and `30`. diff --git a/src/doc/trpl/looping.md b/src/doc/trpl/looping.md index 2985477085e..28f02b1ffe1 100644 --- a/src/doc/trpl/looping.md +++ b/src/doc/trpl/looping.md @@ -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; diff --git a/src/doc/trpl/macros.md b/src/doc/trpl/macros.md index 8f4db3eee5a..e0bccb1b86f 100644 --- a/src/doc/trpl/macros.md +++ b/src/doc/trpl/macros.md @@ -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 } diff --git a/src/doc/trpl/match.md b/src/doc/trpl/match.md index 1833b05591b..73bc775a1b2 100644 --- a/src/doc/trpl/match.md +++ b/src/doc/trpl/match.md @@ -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", }); } ``` diff --git a/src/doc/trpl/ownership.md b/src/doc/trpl/ownership.md index 7a397ce5354..9ced5bb656c 100644 --- a/src/doc/trpl/ownership.md +++ b/src/doc/trpl/ownership.md @@ -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(&mut self, args: &[T]) -> &mut Command // elided +fn args(&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 diff --git a/src/doc/trpl/patterns.md b/src/doc/trpl/patterns.md index c54d502b4ed..5c7b406a6fc 100644 --- a/src/doc/trpl/patterns.md +++ b/src/doc/trpl/patterns.md @@ -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), diff --git a/src/doc/trpl/plugins.md b/src/doc/trpl/plugins.md index 4cd39d407a2..6e8e2c7ffe2 100644 --- a/src/doc/trpl/plugins.md +++ b/src/doc/trpl/plugins.md @@ -1,4 +1,4 @@ -% The Rust Compiler Plugins Guide +% Compiler Plugins
@@ -68,7 +68,7 @@ use rustc::plugin::Registry; fn expand_rn(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree]) -> Box { - 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. diff --git a/src/doc/trpl/pointers.md b/src/doc/trpl/pointers.md index 6832d75245e..d74c10b8145 100644 --- a/src/doc/trpl/pointers.md +++ b/src/doc/trpl/pointers.md @@ -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 { *x + 1 } +fn succ(x: Box) -> 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 { *x + 1 } +fn box_succ(x: Box) -> i32 { *x + 1 } -fn rc_succ(x: Rc) -> int { *x + 1 } +fn rc_succ(x: Rc) -> 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 { } fn main() { - let list: List = List::Cons(1, Box::new(List::Cons(2, Box::new(List::Cons(3, Box::new(List::Nil)))))); + let list: List = 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) -> Box { @@ -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 { diff --git a/src/doc/trpl/standard-input.md b/src/doc/trpl/standard-input.md index c4d171bb3a9..7145139bba5 100644 --- a/src/doc/trpl/standard-input.md +++ b/src/doc/trpl/standard-input.md @@ -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 - .ok() // Option + let input = io::stdin() // std::io::stdio::StdinReader + .read_line() // IoResult + .ok() // Option .expect("Failed to read line"); // String println!("{}", input); diff --git a/src/doc/trpl/testing.md b/src/doc/trpl/testing.md index aefc7d7aa3d..1c93fd351b6 100644 --- a/src/doc/trpl/testing.md +++ b/src/doc/trpl/testing.md @@ -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(&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) }); ``` diff --git a/src/doc/trpl/threads.md b/src/doc/trpl/threads.md index 4c6a7f1323f..1bad09b4b6e 100644 --- a/src/doc/trpl/threads.md +++ b/src/doc/trpl/threads.md @@ -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, Receiver) = channel(); +let (tx, rx): (mpsc::Sender, mpsc::Receiver) = 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, Receiver) = channel(); +```rust +# use std::sync::mpsc; +let (tx, rx): (mpsc::Sender, mpsc::Receiver) = 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::(); +# let (tx, rx) = mpsc::channel::(); # 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::>(); // 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::()); 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::()); # 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>`. `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> = Thread::spawn(move || { +# fn calculate_result() -> i32 { 0 } +let result: Result> = Thread::spawn(move || { if some_condition() { calculate_result() } else { diff --git a/src/doc/trpl/traits.md b/src/doc/trpl/traits.md index 96322296407..d12480d7dd9 100644 --- a/src/doc/trpl/traits.md +++ b/src/doc/trpl/traits.md @@ -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 diff --git a/src/doc/trpl/unsafe.md b/src/doc/trpl/unsafe.md index 075340660df..de6d311be57 100644 --- a/src/doc/trpl/unsafe.md +++ b/src/doc/trpl/unsafe.md @@ -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 Drop for Unique { // 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(x: T) -> U; - fn offset(dst: *const T, offset: int) -> *const T; + fn offset(dst: *const T, offset: isize) -> *const T; } ``` @@ -665,24 +665,24 @@ extern { pub struct Box(*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 } diff --git a/src/doc/trpl/variable-bindings.md b/src/doc/trpl/variable-bindings.md index e57fc7a1206..41c0e9de9b5 100644 --- a/src/doc/trpl/variable-bindings.md +++ b/src/doc/trpl/variable-bindings.md @@ -1,4 +1,4 @@ -% Variable bindings +% Variable Bindings The first thing we'll learn about are *variable bindings*. They look like this: diff --git a/src/libcollections/bit.rs b/src/libcollections/bit.rs index 82e5af67ae3..efd056b0d66 100644 --- a/src/libcollections/bit.rs +++ b/src/libcollections/bit.rs @@ -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, @@ -1107,7 +1107,7 @@ impl<'a> RandomAccessIterator for Iter<'a> { /// assert!(bv[3]); /// ``` #[derive(Clone)] -#[stable] +#[unstable = "RFC 509"] pub struct BitvSet { bitv: Bitv, } diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs index 54ab26c4f77..e222373ff59 100644 --- a/src/libcollections/lib.rs +++ b/src/libcollections/lib.rs @@ -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; diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index ec4007c4c6d..963cb48db07 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -115,7 +115,6 @@ //! } //! # fn calc_span_tree(&self) -> Vec<(uint, uint)> { vec![] } //! } -//! # fn main() { } //! ``` //! //! ## Mutating implementations of `clone` diff --git a/src/libcore/finally.rs b/src/libcore/finally.rs index 4c2a2ff1086..ed3612bded0 100644 --- a/src/libcore/finally.rs +++ b/src/libcore/finally.rs @@ -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 \ diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs index 3d3b9f8cf65..1c37126e8e9 100644 --- a/src/libcore/macros.rs +++ b/src/libcore/macros.rs @@ -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] diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs index 715a79abe85..99ba9666cd2 100644 --- a/src/libcore/marker.rs +++ b/src/libcore/marker.rs @@ -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, +/// } +/// ``` +/// +/// The `PointList` `struct` cannot implement `Copy`, because `Vec` 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::()` 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 Clone for ContravariantType { /// "interior" mutability: /// /// ``` -/// pub struct Cell { value: T } -/// # fn main() {} +/// struct Cell { value: T } /// ``` /// /// The type system would infer that `value` is only read here and diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index e7eb307689f..7d41c3fc5a5 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -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 for Foo { +/// impl Index 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 { /// /// # 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 for Foo { +/// impl IndexMut 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"] diff --git a/src/libcore/prelude.rs b/src/libcore/prelude.rs index c3bb9c91557..da3f180d7e1 100644 --- a/src/libcore/prelude.rs +++ b/src/libcore/prelude.rs @@ -21,11 +21,7 @@ //! # Example //! //! ```ignore -//! # fn main() { -//! #![feature(globs)] -//! //! use core::prelude::*; -//! # } //! ``` // Reexported core operators diff --git a/src/libcore/result.rs b/src/libcore/result.rs index 110bce5c124..1ab810f937d 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -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. diff --git a/src/liblibc/lib.rs b/src/liblibc/lib.rs index deab0cabfbe..7fb609b4c94 100644 --- a/src/liblibc/lib.rs +++ b/src/liblibc/lib.rs @@ -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; diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index b79f19413ef..a283fdf36a9 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -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 diff --git a/src/libstd/bitflags.rs b/src/librustc_bitflags/lib.rs similarity index 97% rename from src/libstd/bitflags.rs rename to src/librustc_bitflags/lib.rs index 3a059766fef..c47a525552d 100644 --- a/src/libstd/bitflags.rs +++ b/src/librustc_bitflags/lib.rs @@ -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"] diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs index 0d1836e0144..59676fa3504 100644 --- a/src/librustc_llvm/lib.rs +++ b/src/librustc_llvm/lib.rs @@ -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::*; diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 7743a437858..22064a35058 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -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; diff --git a/src/libstd/fmt.rs b/src/libstd/fmt.rs index 907925e93d3..36afa0956d2 100644 --- a/src/libstd/fmt.rs +++ b/src/libstd/fmt.rs @@ -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`. diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index bab4dafd090..e2b71cd43af 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -934,16 +934,15 @@ unsafe fn slice_vec_capacity<'a, T>(v: &'a mut Vec, 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: R) {} -/// # fn foo() { /// use std::io; /// use std::io::ByRefReader; /// use std::io::util::LimitReader; /// +/// fn process_input(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, 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: R) {} -/// # fn foo () { /// use std::io::util::TeeReader; /// use std::io::{stdin, ByRefWriter}; /// +/// fn process_input(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 { diff --git a/src/libstd/io/net/pipe.rs b/src/libstd/io/net/pipe.rs index 42d9fff6d15..61d164d21e3 100644 --- a/src/libstd/io/net/pipe.rs +++ b/src/libstd/io/net/pipe.rs @@ -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}; /// diff --git a/src/libstd/io/net/tcp.rs b/src/libstd/io/net/tcp.rs index 6a3f5fcb2c6..4978085fa4f 100644 --- a/src/libstd/io/net/tcp.rs +++ b/src/libstd/io/net/tcp.rs @@ -272,12 +272,10 @@ impl sys_common::AsInner 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; diff --git a/src/libstd/io/timer.rs b/src/libstd/io/timer.rs index 8a0445be471..844a97dea2d 100644 --- a/src/libstd/io/timer.rs +++ b/src/libstd/io/timer.rs @@ -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; diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 182344452a4..2553bbdf523 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -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. */ diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs index a420c841d25..8a8d14c4f3a 100644 --- a/src/libstd/macros.rs +++ b/src/libstd/macros.rs @@ -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()); diff --git a/src/libstd/sync/future.rs b/src/libstd/sync/future.rs index 568c24446e7..36bbc5ff5b4 100644 --- a/src/libstd/sync/future.rs +++ b/src/libstd/sync/future.rs @@ -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()) //! ``` diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 9c947f422e9..096e96b003b 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -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 diff --git a/src/test/compile-fail/unsupported-cast.rs b/src/test/compile-fail/unsupported-cast.rs index 205c912f5a0..ca17c898ec3 100644 --- a/src/test/compile-fail/unsupported-cast.rs +++ b/src/test/compile-fail/unsupported-cast.rs @@ -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. }