From eb002667a2942272f8cf7a451b9004a21d80cf96 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Sat, 25 Apr 2015 12:06:40 -0400 Subject: [PATCH 01/19] Backport of https://github.com/rust-lang/rust/pull/24783 Only backporting the style portion, as changing the test suite is needless churn, and the book/reference are getting their own imports at the end. --- src/doc/style/testing/unit.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/doc/style/testing/unit.md b/src/doc/style/testing/unit.md index 813660d8fdfb9..dbbe9fc3ac6da 100644 --- a/src/doc/style/testing/unit.md +++ b/src/doc/style/testing/unit.md @@ -1,10 +1,10 @@ % Unit testing -Unit tests should live in a `test` submodule at the bottom of the module they -test. Mark the `test` submodule with `#[cfg(test)]` so it is only compiled when +Unit tests should live in a `tests` submodule at the bottom of the module they +test. Mark the `tests` submodule with `#[cfg(test)]` so it is only compiled when testing. -The `test` module should contain: +The `tests` module should contain: * Imports needed only for testing. * Functions marked with `#[test]` striving for full coverage of the parent module's @@ -17,7 +17,7 @@ For example: // Excerpt from std::str #[cfg(test)] -mod test { +mod tests { #[test] fn test_eq() { assert!((eq(&"".to_owned(), &"".to_owned()))); From 1d7bd95c38bb49057c7184e597394fae245a7eb6 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Wed, 22 Apr 2015 09:42:36 -0400 Subject: [PATCH 02/19] Remove doc-comment default::Default imports In 8f5b5f94dcdb9884737dfbc8efd893d1d70f0b14, `default::Default` was added to the prelude, so these imports are no longer necessary. --- src/liballoc/rc.rs | 1 - src/libcore/default.rs | 9 --------- src/libstd/tuple.rs | 2 -- 3 files changed, 12 deletions(-) diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 67805d10a4a63..2ee229ab1dfc5 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -459,7 +459,6 @@ impl Default for Rc { /// /// ``` /// use std::rc::Rc; - /// use std::default::Default; /// /// let x: Rc = Default::default(); /// ``` diff --git a/src/libcore/default.rs b/src/libcore/default.rs index 910cf805f3998..f5103d394eef0 100644 --- a/src/libcore/default.rs +++ b/src/libcore/default.rs @@ -24,8 +24,6 @@ //! How can we define some default values? You can use `Default`: //! //! ``` -//! use std::default::Default; -//! //! #[derive(Default)] //! struct SomeOptions { //! foo: i32, @@ -42,8 +40,6 @@ //! If you have your own type, you need to implement `Default` yourself: //! //! ``` -//! use std::default::Default; -//! //! enum Kind { //! A, //! B, @@ -70,7 +66,6 @@ //! If you want to override a particular option, but still retain the other defaults: //! //! ``` -//! # use std::default::Default; //! # #[derive(Default)] //! # struct SomeOptions { //! # foo: i32, @@ -109,8 +104,6 @@ pub trait Default { /// Using built-in default values: /// /// ``` - /// use std::default::Default; - /// /// let i: i8 = Default::default(); /// let (x, y): (Option, f64) = Default::default(); /// let (a, b, (c, d)): (i32, u32, (bool, bool)) = Default::default(); @@ -119,8 +112,6 @@ pub trait Default { /// Making your own: /// /// ``` - /// use std::default::Default; - /// /// enum Kind { /// A, /// B, diff --git a/src/libstd/tuple.rs b/src/libstd/tuple.rs index 41b70889c9f27..26c1597f3a01a 100644 --- a/src/libstd/tuple.rs +++ b/src/libstd/tuple.rs @@ -43,8 +43,6 @@ //! Using traits implemented for tuples: //! //! ``` -//! use std::default::Default; -//! //! let a = (1, 2); //! let b = (3, 4); //! assert!(a != b); From 31859708cb8ec750236c6611d40116925854096a Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Tue, 21 Apr 2015 11:10:56 -0400 Subject: [PATCH 03/19] Add examples by @pnkfelix to fmt precision Fixes #24656 --- src/libcollections/fmt.rs | 67 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 62 insertions(+), 5 deletions(-) diff --git a/src/libcollections/fmt.rs b/src/libcollections/fmt.rs index a59a88ffe30e4..37e6a32bb2d2f 100644 --- a/src/libcollections/fmt.rs +++ b/src/libcollections/fmt.rs @@ -398,14 +398,71 @@ //! //! ## Precision //! -//! For non-numeric types, this can be considered a "maximum width". If the -//! resulting string is longer than this width, then it is truncated down to -//! this many characters and only those are emitted. +//! For non-numeric types, this can be considered a "maximum width". If the resulting string is +//! longer than this width, then it is truncated down to this many characters and only those are +//! emitted. //! //! For integral types, this has no meaning currently. //! -//! For floating-point types, this indicates how many digits after the decimal -//! point should be printed. +//! For floating-point types, this indicates how many digits after the decimal point should be +//! printed. +//! +//! There are three possible ways to specify the desired `precision`: +//! +//! There are three possible ways to specify the desired `precision`: +//! 1. An integer `.N`, +//! 2. an integer followed by dollar sign `.N$`, or +//! 3. an asterisk `.*`. +//! +//! The first specification, `.N`, means the integer `N` itself is the precision. +//! +//! The second, `.N$`, means use format *argument* `N` (which must be a `usize`) as the precision. +//! +//! Finally, `.*` means that this `{...}` is associated with *two* format inputs rather than one: +//! the first input holds the `usize` precision, and the second holds the value to print. Note +//! that in this case, if one uses the format string `{:.*}`, then the `` part +//! refers to the *value* to print, and the `precision` must come in the input preceding ``. +//! +//! For example, these: +//! +//! ``` +//! // Hello {arg 0 (x)} is {arg 1 (0.01} with precision specified inline (5)} +//! println!("Hello {0} is {1:.5}", "x", 0.01); +//! +//! // Hello {arg 1 (x)} is {arg 2 (0.01} with precision specified in arg 0 (5)} +//! println!("Hello {1} is {2:.0$}", 5, "x", 0.01); +//! +//! // Hello {arg 0 (x)} is {arg 2 (0.01} with precision specified in arg 1 (5)} +//! println!("Hello {0} is {2:.1$}", "x", 5, 0.01); +//! +//! // Hello {next arg (x)} is {second of next two args (0.01} with precision +//! // specified in first of next two args (5)} +//! println!("Hello {} is {:.*}", "x", 5, 0.01); +//! +//! // Hello {next arg (x)} is {arg 2 (0.01} with precision +//! // specified in its predecessor (5)} +//! println!("Hello {} is {2:.*}", "x", 5, 0.01); +//! ``` +//! +//! All print the same thing: +//! +//! ```text +//! Hello x is 0.01000 +//! ``` +//! +//! While these: +//! +//! ``` +//! println!("{}, `{name:.*}` has 3 fractional digits", "Hello", 3, name=1234.56); +//! println!("{}, `{name:.*}` has 3 characters", "Hello", 3, name="1234.56"); +//! ``` +//! +//! print two significantly different things: +//! +//! ```text +//! Hello, `1234.560` has 3 fractional digits +//! Hello, `123` has 3 characters +//! ``` //! //! # Escaping //! From 4ceda40d46961c1980ab6bf3552be8d228f16975 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Fri, 24 Apr 2015 18:59:47 -0400 Subject: [PATCH 04/19] Whoops, please tidy --- src/libcollections/fmt.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/libcollections/fmt.rs b/src/libcollections/fmt.rs index 37e6a32bb2d2f..436fbd52213ff 100644 --- a/src/libcollections/fmt.rs +++ b/src/libcollections/fmt.rs @@ -406,11 +406,11 @@ //! //! For floating-point types, this indicates how many digits after the decimal point should be //! printed. -//! +//! //! There are three possible ways to specify the desired `precision`: //! -//! There are three possible ways to specify the desired `precision`: -//! 1. An integer `.N`, +//! There are three possible ways to specify the desired `precision`: +//! 1. An integer `.N`, //! 2. an integer followed by dollar sign `.N$`, or //! 3. an asterisk `.*`. //! @@ -422,23 +422,23 @@ //! the first input holds the `usize` precision, and the second holds the value to print. Note //! that in this case, if one uses the format string `{:.*}`, then the `` part //! refers to the *value* to print, and the `precision` must come in the input preceding ``. -//! -//! For example, these: +//! +//! For example, these: //! //! ``` //! // Hello {arg 0 (x)} is {arg 1 (0.01} with precision specified inline (5)} //! println!("Hello {0} is {1:.5}", "x", 0.01); -//! +//! //! // Hello {arg 1 (x)} is {arg 2 (0.01} with precision specified in arg 0 (5)} //! println!("Hello {1} is {2:.0$}", 5, "x", 0.01); //! //! // Hello {arg 0 (x)} is {arg 2 (0.01} with precision specified in arg 1 (5)} //! println!("Hello {0} is {2:.1$}", "x", 5, 0.01); -//! +//! //! // Hello {next arg (x)} is {second of next two args (0.01} with precision //! // specified in first of next two args (5)} //! println!("Hello {} is {:.*}", "x", 5, 0.01); -//! +//! //! // Hello {next arg (x)} is {arg 2 (0.01} with precision //! // specified in its predecessor (5)} //! println!("Hello {} is {2:.*}", "x", 5, 0.01); @@ -458,7 +458,7 @@ //! ``` //! //! print two significantly different things: -//! +//! //! ```text //! Hello, `1234.560` has 3 fractional digits //! Hello, `123` has 3 characters From b40356098a24ab40700744952cf37164537d44d7 Mon Sep 17 00:00:00 2001 From: Matt Brubeck Date: Mon, 20 Apr 2015 17:51:56 -0700 Subject: [PATCH 05/19] Update reference to old_io in fmt docs --- src/libcollections/fmt.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcollections/fmt.rs b/src/libcollections/fmt.rs index 436fbd52213ff..1dac90dc34128 100644 --- a/src/libcollections/fmt.rs +++ b/src/libcollections/fmt.rs @@ -246,7 +246,7 @@ //! //! ```ignore //! format! // described above -//! write! // first argument is a &mut old_io::Writer, the destination +//! write! // first argument is a &mut io::Write, the destination //! writeln! // same as write but appends a newline //! print! // the format string is printed to the standard output //! println! // same as print but appends a newline From 051fb376bfaf7bc378228007d91b43f933122588 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Mon, 20 Apr 2015 10:05:57 -0400 Subject: [PATCH 06/19] Clean up Box documentation. Without the `box` keyword, one of these two reasons is not correct, so let's just eliminate this section and elaborate on the reason for the legit use case inline. Fixes #24511 --- src/liballoc/boxed.rs | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index e293a024f8e08..7696abd659f02 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -10,14 +10,9 @@ //! A pointer type for heap allocation. //! -//! `Box`, casually referred to as a 'box', provides the simplest form of -//! heap allocation in Rust. Boxes provide ownership for this allocation, and -//! drop their contents when they go out of scope. -//! -//! Boxes are useful in two situations: recursive data structures, and -//! occasionally when returning data. [The Pointer chapter of the -//! Book](../../../book/pointers.html#best-practices-1) explains these cases in -//! detail. +//! `Box`, casually referred to as a 'box', provides the simplest form of heap allocation in +//! Rust. Boxes provide ownership for this allocation, and drop their contents when they go out of +//! scope. //! //! # Examples //! @@ -43,6 +38,16 @@ //! ``` //! //! This will print `Cons(1, Box(Cons(2, Box(Nil))))`. +//! +//! Recursive structures must be boxed, because if the definition of `Cons` looked like this: +//! +//! ```rust,ignore +//! Cons(T, List), +//! ``` +//! +//! It wouldn't work. This is because the size of a `List` depends on how many elements are in the +//! list, and so we don't know how much memory to allocate for a `Cons`. By introducing a `Box`, +//! which has a defined size, we know how big `Cons` needs to be. #![stable(feature = "rust1", since = "1.0.0")] From 75051c6d2d24443248971118acfd1bc601e1f02a Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Mon, 20 Apr 2015 09:59:58 -0400 Subject: [PATCH 07/19] remove bad example from PartialEq docs Fixes #24173 --- src/libcore/cmp.rs | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index efe1179621de5..dd59ceff577a8 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -14,27 +14,6 @@ //! implement comparison operators. Rust programs may implement `PartialOrd` to overload the `<`, //! `<=`, `>`, and `>=` operators, and may implement `PartialEq` to overload the `==` and `!=` //! operators. -//! -//! For example, to define a type with a customized definition for the PartialEq operators, you -//! could do the following: -//! -//! ``` -//! # #![feature(core)] -//! struct FuzzyNum { -//! num: i32, -//! } -//! -//! impl PartialEq for FuzzyNum { -//! // Our custom eq allows numbers which are near each other to be equal! :D -//! fn eq(&self, other: &FuzzyNum) -> bool { -//! (self.num - other.num).abs() < 5 -//! } -//! } -//! -//! // Now these binary operators will work when applied! -//! assert!(FuzzyNum { num: 37 } == FuzzyNum { num: 34 }); -//! assert!(FuzzyNum { num: 25 } != FuzzyNum { num: 57 }); -//! ``` #![stable(feature = "rust1", since = "1.0.0")] From abbd9dcf7da5639f2f2c693171f0e79b88018eaf Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Mon, 20 Apr 2015 09:55:07 -0400 Subject: [PATCH 08/19] Make iterator struct docs more consistent. Fixes #24008. --- src/libcore/str/mod.rs | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 0bc09e4cf791e..31431f4496226 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -340,7 +340,7 @@ impl<'a> DoubleEndedIterator for CharIndices<'a> { /// External iterator for a string's bytes. /// Use with the `std::iter` module. /// -/// Created with `str::bytes` +/// Created with the method `.bytes()`. #[stable(feature = "rust1", since = "1.0.0")] #[derive(Clone)] pub struct Bytes<'a>(Map, BytesDeref>); @@ -635,10 +635,10 @@ impl<'a, P: Pattern<'a>> SplitInternal<'a, P> { generate_pattern_iterators! { forward: - /// Return type of `str::split()` + /// Created with the method `.split()`. struct Split; reverse: - /// Return type of `str::rsplit()` + /// Created with the method `.rsplit()`. struct RSplit; stability: #[stable(feature = "rust1", since = "1.0.0")] @@ -649,10 +649,10 @@ generate_pattern_iterators! { generate_pattern_iterators! { forward: - /// Return type of `str::split_terminator()` + /// Created with the method `.split_terminator()`. struct SplitTerminator; reverse: - /// Return type of `str::rsplit_terminator()` + /// Created with the method `.rsplit_terminator()`. struct RSplitTerminator; stability: #[stable(feature = "rust1", since = "1.0.0")] @@ -695,10 +695,10 @@ impl<'a, P: Pattern<'a>> SplitNInternal<'a, P> { generate_pattern_iterators! { forward: - /// Return type of `str::splitn()` + /// Created with the method `.splitn()`. struct SplitN; reverse: - /// Return type of `str::rsplitn()` + /// Created with the method `.rsplitn()`. struct RSplitN; stability: #[stable(feature = "rust1", since = "1.0.0")] @@ -729,10 +729,10 @@ impl<'a, P: Pattern<'a>> MatchIndicesInternal<'a, P> { generate_pattern_iterators! { forward: - /// Return type of `str::match_indices()` + /// Created with the method `.match_indices()`. struct MatchIndices; reverse: - /// Return type of `str::rmatch_indices()` + /// Created with the method `.rmatch_indices()`. struct RMatchIndices; stability: #[unstable(feature = "core", @@ -770,10 +770,10 @@ impl<'a, P: Pattern<'a>> MatchesInternal<'a, P> { generate_pattern_iterators! { forward: - /// Return type of `str::matches()` + /// Created with the method `.matches()`. struct Matches; reverse: - /// Return type of `str::rmatches()` + /// Created with the method `.rmatches()`. struct RMatches; stability: #[unstable(feature = "core", reason = "type got recently added")] @@ -782,7 +782,7 @@ generate_pattern_iterators! { delegate double ended; } -/// Return type of `str::lines()` +/// Created with the method `.lines()`. #[stable(feature = "rust1", since = "1.0.0")] #[derive(Clone)] pub struct Lines<'a>(SplitTerminator<'a, char>); @@ -810,7 +810,7 @@ impl<'a> DoubleEndedIterator for Lines<'a> { } } -/// Return type of `str::lines_any()` +/// Created with the method `.lines_any()`. #[stable(feature = "rust1", since = "1.0.0")] #[derive(Clone)] pub struct LinesAny<'a>(Map, LinesAnyMap>); From 6ab15dc0994bd18061e5ae8e620dacffee4c71f0 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Mon, 20 Apr 2015 08:57:06 -0400 Subject: [PATCH 09/19] Simplify alloc::arc::Arc example in doc-comment As far as I can tell, this conversion to integer to floating point does not need to happen and is beside the point --- src/liballoc/arc.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index 93af336ce0a1a..554ca3ea539cb 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -102,7 +102,7 @@ use heap::deallocate; /// use std::thread; /// /// fn main() { -/// let numbers: Vec<_> = (0..100u32).map(|i| i as f32).collect(); +/// let numbers: Vec<_> = (0..100u32).collect(); /// let shared_numbers = Arc::new(numbers); /// /// for _ in 0..10 { From 5b986198e3e4149bcc54a48cd8e3e60cf4b1fb7a Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Sun, 19 Apr 2015 12:18:51 -0400 Subject: [PATCH 10/19] Fix typos in code comments --- src/libstd/path.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libstd/path.rs b/src/libstd/path.rs index 7d4d4bc4c66fd..e8052041aeb30 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -704,7 +704,7 @@ impl<'a> Components<'a> { (comp.len() + extra, self.parse_single_component(comp)) } - // trim away repeated separators (i.e. emtpy components) on the left + // trim away repeated separators (i.e. empty components) on the left fn trim_left(&mut self) { while !self.path.is_empty() { let (size, comp) = self.parse_next_component(); @@ -716,7 +716,7 @@ impl<'a> Components<'a> { } } - // trim away repeated separators (i.e. emtpy components) on the right + // trim away repeated separators (i.e. empty components) on the right fn trim_right(&mut self) { while self.path.len() > self.len_before_body() { let (size, comp) = self.parse_next_component_back(); From 44c5aa534cda7e945619c2d73daa8800e563c60e Mon Sep 17 00:00:00 2001 From: York Xiang Date: Mon, 20 Apr 2015 00:07:23 +0800 Subject: [PATCH 11/19] Improve doc for `Result::unwrap()` --- src/libcore/result.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcore/result.rs b/src/libcore/result.rs index 35cb8398cee92..919f8d9c73a62 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -706,8 +706,8 @@ impl Result { /// /// # Panics /// - /// Panics if the value is an `Err`, with a custom panic message provided - /// by the `Err`'s value. + /// Panics if the value is an `Err`, with a panic message provided by the + /// `Err`'s value. /// /// # Examples /// From 6a31baa701a7cac9c301955a20e4658330257468 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Sat, 18 Apr 2015 17:55:31 -0400 Subject: [PATCH 12/19] Remove the 30 minute intro Fixes #24569. --- src/doc/intro.md | 585 +---------------------------------------------- 1 file changed, 2 insertions(+), 583 deletions(-) diff --git a/src/doc/intro.md b/src/doc/intro.md index e6d560d8122e6..48712d8d49b55 100644 --- a/src/doc/intro.md +++ b/src/doc/intro.md @@ -1,586 +1,5 @@ % A 30-minute Introduction to Rust -Rust is a modern systems programming language focusing on safety and speed. It -accomplishes these goals by being memory safe without using garbage collection. +This introduction is now deprecated. Please see [the introduction to the book][intro]. -This introduction will give you a rough idea of what Rust is like, eliding many -details. It does not require prior experience with systems programming, but you -may find the syntax easier if you've used a "curly brace" programming language -before, like C or JavaScript. The concepts are more important than the syntax, -so don't worry if you don't get every last detail: you can read [The -Rust Programming Language](book/index.html) to get a more complete explanation. - -Because this is about high-level concepts, you don't need to actually install -Rust to follow along. If you'd like to anyway, check out [the -homepage](http://rust-lang.org) for explanation. - -To show off Rust, let's talk about how easy it is to get started with Rust. -Then, we'll talk about Rust's most interesting feature, *ownership*, and -then discuss how it makes concurrency easier to reason about. Finally, -we'll talk about how Rust breaks down the perceived dichotomy between speed -and safety. - -# Tools - -Getting started on a new Rust project is incredibly easy, thanks to Rust's -package manager, [Cargo](https://crates.io/). - -To start a new project with Cargo, use `cargo new`: - -```{bash} -$ cargo new hello_world --bin -``` - -We're passing `--bin` because we're making a binary program: if we -were making a library, we'd leave it off. - -Let's check out what Cargo has generated for us: - -```{bash} -$ cd hello_world -$ tree . -. -├── Cargo.toml -└── src - └── main.rs - -1 directory, 2 files -``` - -This is all we need to get started. First, let's check out `Cargo.toml`: - -```{toml} -[package] - -name = "hello_world" -version = "0.0.1" -authors = ["Your Name "] -``` - -This is called a *manifest*, and it contains all of the metadata that Cargo -needs to compile your project. - -Here's what's in `src/main.rs`: - -```{rust} -fn main() { - println!("Hello, world!"); -} -``` - -Cargo generated a "Hello World" for us. We'll talk more about the syntax here -later, but that's what Rust code looks like! Let's compile and run it: - -```{bash} -$ cargo run - Compiling hello_world v0.0.1 (file:///Users/you/src/hello_world) - Running `target/hello_world` -Hello, world! -``` - -Using an external dependency in Rust is incredibly easy. You add a line to -your `Cargo.toml`: - -```{toml} -[package] - -name = "hello_world" -version = "0.0.1" -authors = ["Your Name "] - -[dependencies.semver] - -git = "https://github.com/rust-lang/semver.git" -``` - -You added the `semver` library, which parses version numbers and compares them -according to the [SemVer specification](http://semver.org/). - -Now, you can pull in that library using `extern crate` in -`main.rs`. - -```{rust,ignore} -extern crate semver; - -use semver::Version; - -fn main() { - assert!(Version::parse("1.2.3") == Ok(Version { - major: 1u64, - minor: 2u64, - patch: 3u64, - pre: vec!(), - build: vec!(), - })); - - println!("Versions compared successfully!"); -} -``` - -Again, we'll discuss the exact details of all of this syntax soon. For now, -let's compile and run it: - -```{bash} -$ cargo run - Updating git repository `https://github.com/rust-lang/semver.git` - Compiling semver v0.0.1 (https://github.com/rust-lang/semver.git#bf739419) - Compiling hello_world v0.0.1 (file:///home/you/projects/hello_world) - Running `target/hello_world` -Versions compared successfully! -``` - -Because we only specified a repository without a version, if someone else were -to try out our project at a later date, when `semver` was updated, they would -get a different, possibly incompatible version. To solve this problem, Cargo -produces a file, `Cargo.lock`, which records the versions of any dependencies. -This gives us repeatable builds. - -There is a lot more here, and this is a whirlwind tour, but you should feel -right at home if you've used tools like [Bundler](http://bundler.io/), -[npm](https://www.npmjs.org/), or [pip](https://pip.pypa.io/en/latest/). -There's no `Makefile`s or endless `autotools` output here. (Rust's tooling does -[play nice with external libraries written in those -tools](http://doc.crates.io/build-script.html), if you need to.) - -Enough about tools, let's talk code! - -# Ownership - -Rust's defining feature is "memory safety without garbage collection". Let's -take a moment to talk about what that means. *Memory safety* means that the -programming language eliminates certain kinds of bugs, such as [buffer -overflows](https://en.wikipedia.org/wiki/Buffer_overflow) and [dangling -pointers](https://en.wikipedia.org/wiki/Dangling_pointer). These problems occur -when you have unrestricted access to memory. As an example, here's some Ruby -code: - -```{ruby} -v = [] - -v.push("Hello") - -x = v[0] - -v.push("world") - -puts x -``` - -We make an array, `v`, and then call `push` on it. `push` is a method which -adds an element to the end of an array. - -Next, we make a new variable, `x`, that's equal to the first element of -the array. Simple, but this is where the "bug" will appear. - -Let's keep going. We then call `push` again, pushing "world" onto the -end of the array. `v` now is `["Hello", "world"]`. - -Finally, we print `x` with the `puts` method. This prints "Hello." - -All good? Let's go over a similar, but subtly different example, in C++: - -```{cpp} -#include -#include -#include - -int main() { - std::vector v; - - v.push_back("Hello"); - - std::string& x = v[0]; - - v.push_back("world"); - - std::cout << x; -} -``` - -It's a little more verbose due to the static typing, but it's almost the same -thing. We make a `std::vector` of `std::string`s, we call `push_back` (same as -`push`) on it, take a reference to the first element of the vector, call -`push_back` again, and then print out the reference. - -There's two big differences here: one, they're not _exactly_ the same thing, -and two... - -```{bash} -$ g++ hello.cpp -Wall -Werror -$ ./a.out -Segmentation fault (core dumped) -``` - -A crash! (Note that this is actually system-dependent. Because referring to an -invalid reference is undefined behavior, the compiler can do anything, -including the right thing!) Even though we compiled with flags to give us as -many warnings as possible, and to treat those warnings as errors, we got no -errors. When we ran the program, it crashed. - -Why does this happen? When we append to an array, its length changes. Since -its length changes, we may need to allocate more memory. In Ruby, this happens -as well, we just don't think about it very often. So why does the C++ version -segfault when we allocate more memory? - -The answer is that in the C++ version, `x` is a *reference* to the memory -location where the first element of the array is stored. But in Ruby, `x` is a -standalone value, not connected to the underlying array at all. Let's dig into -the details for a moment. Your program has access to memory, provided to it by -the operating system. Each location in memory has an address. So when we make -our vector, `v`, it's stored in a memory location somewhere: - -| location | name | value | -|----------|------|-------| -| 0x30 | v | | - -(Address numbers made up, and in hexadecimal. Those of you with deep C++ -knowledge, there are some simplifications going on here, like the lack of an -allocated length for the vector. This is an introduction.) - -When we push our first string onto the array, we allocate some memory, -and `v` refers to it: - -| location | name | value | -|----------|------|----------| -| 0x30 | v | 0x18 | -| 0x18 | | "Hello" | - -We then make a reference to that first element. A reference is a variable -that points to a memory location, so its value is the memory location of -the `"Hello"` string: - -| location | name | value | -|----------|------|----------| -| 0x30 | v | 0x18 | -| 0x18 | | "Hello" | -| 0x14 | x | 0x18 | - -When we push `"world"` onto the vector with `push_back`, there's no room: -we only allocated one element. So, we need to allocate two elements, -copy the `"Hello"` string over, and update the reference. Like this: - -| location | name | value | -|----------|------|----------| -| 0x30 | v | 0x08 | -| 0x18 | | GARBAGE | -| 0x14 | x | 0x18 | -| 0x08 | | "Hello" | -| 0x04 | | "world" | - -Note that `v` now refers to the new list, which has two elements. It's all -good. But our `x` didn't get updated! It still points at the old location, -which isn't valid anymore. In fact, [the documentation for `push_back` mentions -this](http://en.cppreference.com/w/cpp/container/vector/push_back): - -> If the new `size()` is greater than `capacity()` then all iterators and -> references (including the past-the-end iterator) are invalidated. - -Finding where these iterators and references are is a difficult problem, and -even in this simple case, `g++` can't help us here. While the bug is obvious in -this case, in real code, it can be difficult to track down the source of the -error. - -Before we talk about this solution, why didn't our Ruby code have this problem? -The semantics are a little more complicated, and explaining Ruby's internals is -out of the scope of a guide to Rust. But in a nutshell, Ruby's garbage -collector keeps track of references, and makes sure that everything works as -you might expect. This comes at an efficiency cost, and the internals are more -complex. If you'd really like to dig into the details, [this -article](http://patshaughnessy.net/2012/1/18/seeing-double-how-ruby-shares-string-values) -can give you more information. - -Garbage collection is a valid approach to memory safety, but Rust chooses a -different path. Let's examine what the Rust version of this looks like: - -```{rust,ignore} -fn main() { - let mut v = vec![]; - - v.push("Hello"); - - let x = &v[0]; - - v.push("world"); - - println!("{}", x); -} -``` - -This looks like a bit of both: fewer type annotations, but we do create new -variables with `let`. The method name is `push`, some other stuff is different, -but it's pretty close. So what happens when we compile this code? Does Rust -print `"Hello"`, or does Rust crash? - -Neither. It refuses to compile: - -```bash -$ cargo run - Compiling hello_world v0.0.1 (file:///Users/you/src/hello_world) -main.rs:8:5: 8:6 error: cannot borrow `v` as mutable because it is also borrowed as immutable -main.rs:8 v.push("world"); - ^ -main.rs:6:14: 6:15 note: previous borrow of `v` occurs here; the immutable borrow prevents subsequent moves or mutable borrows of `v` until the borrow ends -main.rs:6 let x = &v[0]; - ^ -main.rs:11:2: 11:2 note: previous borrow ends here -main.rs:1 fn main() { -... -main.rs:11 } - ^ -error: aborting due to previous error -``` - -When we try to mutate the array by `push`ing it the second time, Rust throws -an error. It says that we "cannot borrow v as mutable because it is also -borrowed as immutable." What does it mean by "borrowed"? - -In Rust, the type system encodes the notion of *ownership*. The variable `v` -is an *owner* of the vector. When we make a reference to `v`, we let that -variable (in this case, `x`) *borrow* it for a while. Just like if you own a -book, and you lend it to me, I'm borrowing the book. - -So, when I try to modify the vector with the second call to `push`, I need -to be owning it. But `x` is borrowing it. You can't modify something that -you've lent to someone. And so Rust throws an error. - -So how do we fix this problem? Well, we can make a copy of the element: - - -```{rust} -fn main() { - let mut v = vec![]; - - v.push("Hello"); - - let x = v[0].clone(); - - v.push("world"); - - println!("{}", x); -} -``` - -Note the addition of `clone()`. This creates a copy of the element, leaving -the original untouched. Now, we no longer have two references to the same -memory, and so the compiler is happy. Let's give that a try: - -```{bash} -$ cargo run - Compiling hello_world v0.0.1 (file:///Users/you/src/hello_world) - Running `target/hello_world` -Hello -``` - -Same result. Now, making a copy can be inefficient, so this solution may not be -acceptable. There are other ways to get around this problem, but this is a toy -example, and because we're in an introduction, we'll leave that for later. - -The point is, the Rust compiler and its notion of ownership has saved us from a -bug that would crash the program. We've achieved safety, at compile time, -without needing to rely on a garbage collector to handle our memory. - -# Concurrency - -Rust's ownership model can help in other ways, as well. For example, take -concurrency. Concurrency is a big topic, and an important one for any modern -programming language. Let's take a look at how ownership can help you write -safe concurrent programs. - -Here's an example of a concurrent Rust program: - -```{rust} -# #![feature(scoped)] -use std::thread; - -fn main() { - let guards: Vec<_> = (0..10).map(|_| { - thread::scoped(|| { - println!("Hello, world!"); - }) - }).collect(); -} -``` - -This program creates ten threads, which all print `Hello, world!`. The `scoped` -function takes one argument, a closure, indicated by the double bars `||`. This -closure is executed in a new thread created by `scoped`. The method is called -`scoped` because it returns a 'join guard', which will automatically join the -child thread when it goes out of scope. Because we `collect` these guards into -a `Vec`, and that vector goes out of scope at the end of our program, our -program will wait for every thread to finish before finishing. - -One common form of problem in concurrent programs is a *data race*. -This occurs when two different threads attempt to access the same -location in memory in a non-synchronized way, where at least one of -them is a write. If one thread is attempting to read, and one thread -is attempting to write, you cannot be sure that your data will not be -corrupted. Note the first half of that requirement: two threads that -attempt to access the same location in memory. Rust's ownership model -can track which pointers own which memory locations, which solves this -problem. - -Let's see an example. This Rust code will not compile: - -```{rust,ignore} -# #![feature(scoped)] -use std::thread; - -fn main() { - let mut numbers = vec![1, 2, 3]; - - let guards: Vec<_> = (0..3).map(|i| { - thread::scoped(move || { - numbers[i] += 1; - println!("numbers[{}] is {}", i, numbers[i]); - }) - }).collect(); -} -``` - -It gives us this error: - -```text -7:25: 10:6 error: cannot move out of captured outer variable in an `FnMut` closure -7 thread::scoped(move || { -8 numbers[i] += 1; -9 println!("numbers[{}] is {}", i, numbers[i]); -10 }) -error: aborting due to previous error -``` - -This is a little confusing because there are two closures here: the one passed -to `map`, and the one passed to `thread::scoped`. In this case, the closure for -`thread::scoped` is attempting to reference `numbers`, a `Vec`. This -closure is a `FnOnce` closure, as that’s what `thread::scoped` takes as an -argument. `FnOnce` closures take ownership of their environment. That’s fine, -but there’s one detail: because of `map`, we’re going to make three of these -closures. And since all three try to take ownership of `numbers`, that would be -a problem. That’s what it means by ‘cannot move out of captured outer -variable’: our `thread::scoped` closure wants to take ownership, and it can’t, -because the closure for `map` won’t let it. - -What to do here? Rust has a type that helps us: `Mutex`. Because the threads -are scoped, it is possible to use an _immutable_ reference to `numbers` inside -of the closure. However, Rust prevents us from having multiple _mutable_ -references to the same object, so we need a `Mutex` to be able to modify what -we're sharing. A Mutex will synchronize our accesses, so that we can ensure -that our mutation doesn't cause a data race. - -Here's what using a Mutex looks like: - -```{rust} -# #![feature(scoped)] -use std::thread; -use std::sync::Mutex; - -fn main() { - let numbers = &Mutex::new(vec![1, 2, 3]); - - let guards: Vec<_> = (0..3).map(|i| { - thread::scoped(move || { - let mut array = numbers.lock().unwrap(); - array[i] += 1; - println!("numbers[{}] is {}", i, array[i]); - }) - }).collect(); -} -``` - -We first have to `use` the appropriate library, and then we wrap our vector in -a `Mutex` with the call to `Mutex::new()`. Inside of the loop, the `lock()` -call will return us a reference to the value inside the Mutex, and block any -other calls to `lock()` until said reference goes out of scope. - -We can compile and run this program without error, and in fact, see the -non-deterministic aspect: - -```{shell} -$ cargo run - Compiling hello_world v0.0.1 (file:///Users/you/src/hello_world) - Running `target/hello_world` -numbers[1] is 3 -numbers[0] is 2 -numbers[2] is 4 -$ cargo run - Running `target/hello_world` -numbers[2] is 4 -numbers[1] is 3 -numbers[0] is 2 -``` - -Each time, we can get a slightly different output because the threads are not -guaranteed to run in any set order. If you get the same order every time it is -because each of these threads are very small and complete too fast for their -indeterminate behavior to surface. - -The important part here is that the Rust compiler was able to use ownership to -give us assurance _at compile time_ that we weren't doing something incorrect -with regards to concurrency. In order to share ownership, we were forced to be -explicit and use a mechanism to ensure that it would be properly handled. - -# Safety _and_ Speed - -Safety and speed are always presented as a continuum. At one end of the spectrum, -you have maximum speed, but no safety. On the other end, you have absolute safety -with no speed. Rust seeks to break out of this paradigm by introducing safety at -compile time, ensuring that you haven't done anything wrong, while compiling to -the same low-level code you'd expect without the safety. - -As an example, Rust's ownership system is _entirely_ at compile time. The -safety check that makes this an error about moved values: - -```{rust,ignore} -# #![feature(scoped)] -use std::thread; - -fn main() { - let numbers = vec![1, 2, 3]; - - let guards: Vec<_> = (0..3).map(|i| { - thread::scoped(move || { - println!("{}", numbers[i]); - }) - }).collect(); -} -``` - -carries no runtime penalty. And while some of Rust's safety features do have -a run-time cost, there's often a way to write your code in such a way that -you can remove it. As an example, this is a poor way to iterate through -a vector: - -```{rust} -let vec = vec![1, 2, 3]; - -for i in 0..vec.len() { - println!("{}", vec[i]); -} -``` - -The reason is that the access of `vec[i]` does bounds checking, to ensure -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![1, 2, 3]; - -for x in &vec { - println!("{}", x); -} -``` - -This version uses an iterator that yields each element of the vector in turn. -Because we have a reference to the element, rather than the whole vector itself, -there's no array access bounds to check. - -# Learning More - -I hope that this taste of Rust has given you an idea if Rust is the right -language for you. We talked about Rust's tooling, how encoding ownership into -the type system helps you find bugs, how Rust can help you write correct -concurrent code, and how you don't have to pay a speed cost for much of this -safety. - -To continue your Rustic education, read [The Rust Programming -Language](book/index.html) for a more in-depth exploration of Rust's syntax and -concepts. +[intro]: book/README.html From 88f1b2dc3ad0ff0318c209ee6dd91ec07a9f5fc2 Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Sat, 18 Apr 2015 13:00:40 -0700 Subject: [PATCH 13/19] Update Windows caveats - https://github.com/rust-lang/rust/issues/1237 is closed - `libgcc` is now statically linked: https://github.com/rust-lang/rust/pull/17471 --- src/doc/complement-lang-faq.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/doc/complement-lang-faq.md b/src/doc/complement-lang-faq.md index 8238dd3a5ba42..f7bad3e40214f 100644 --- a/src/doc/complement-lang-faq.md +++ b/src/doc/complement-lang-faq.md @@ -42,10 +42,7 @@ Let the fact that this is an easily countable number be a warning. ## Does it run on Windows? -Yes. All development happens in lockstep on all 3 target platforms (using MinGW, not Cygwin). Note that the Windows implementation currently has some limitations; in particular, the 64-bit build is [not fully supported yet][win64], and all executables created by rustc [depend on libgcc DLL at runtime][libgcc]. - -[win64]: https://github.com/rust-lang/rust/issues/1237 -[libgcc]: https://github.com/rust-lang/rust/issues/11782 +Yes. All development happens in lockstep on all 3 target platforms (using MinGW, not Cygwin). ## Is it OO? How do I do this thing I normally do in an OO language? From f79643837352ef48d6d5e2594145102ba7f53f35 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Sat, 18 Apr 2015 12:45:05 -0400 Subject: [PATCH 14/19] Utilize if..let for get_mut doc-comment examples --- src/libcollections/btree/map.rs | 5 ++--- src/libcollections/vec_deque.rs | 7 ++----- src/libcollections/vec_map.rs | 10 ++++------ src/libstd/collections/hash/map.rs | 5 ++--- 4 files changed, 10 insertions(+), 17 deletions(-) diff --git a/src/libcollections/btree/map.rs b/src/libcollections/btree/map.rs index bd4028db42e0f..291b66939e5ef 100644 --- a/src/libcollections/btree/map.rs +++ b/src/libcollections/btree/map.rs @@ -260,9 +260,8 @@ impl BTreeMap { /// /// let mut map = BTreeMap::new(); /// map.insert(1, "a"); - /// match map.get_mut(&1) { - /// Some(x) => *x = "b", - /// None => (), + /// if let Some(x) = map.get_mut(&1) { + /// *x = "b"; /// } /// assert_eq!(map[&1], "b"); /// ``` diff --git a/src/libcollections/vec_deque.rs b/src/libcollections/vec_deque.rs index fcb06b5631ab3..bbe7830b4238c 100644 --- a/src/libcollections/vec_deque.rs +++ b/src/libcollections/vec_deque.rs @@ -223,11 +223,8 @@ impl VecDeque { /// buf.push_back(3); /// buf.push_back(4); /// buf.push_back(5); - /// match buf.get_mut(1) { - /// None => {} - /// Some(elem) => { - /// *elem = 7; - /// } + /// if let Some(elem) = buf.get_mut(1) { + /// *elem = 7; /// } /// /// assert_eq!(buf[1], 7); diff --git a/src/libcollections/vec_map.rs b/src/libcollections/vec_map.rs index d9cffc74dddda..d473504d54454 100644 --- a/src/libcollections/vec_map.rs +++ b/src/libcollections/vec_map.rs @@ -47,9 +47,8 @@ use vec::Vec; /// /// assert_eq!(months.get(&1), Some(&"Jan")); /// -/// match months.get_mut(&3) { -/// Some(value) => *value = "Venus", -/// None => (), +/// if let Some(value) = months.get_mut(&3) { +/// *value = "Venus"; /// } /// /// assert_eq!(months.get(&3), Some(&"Venus")); @@ -528,9 +527,8 @@ impl VecMap { /// /// let mut map = VecMap::new(); /// map.insert(1, "a"); - /// match map.get_mut(&1) { - /// Some(x) => *x = "b", - /// None => (), + /// if let Some(x) = map.get_mut(&1) { + /// *x = "b"; /// } /// assert_eq!(map[1], "b"); /// ``` diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index c28094d35e401..f9eb21e89aadf 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -1067,9 +1067,8 @@ impl HashMap /// /// let mut map = HashMap::new(); /// map.insert(1, "a"); - /// match map.get_mut(&1) { - /// Some(x) => *x = "b", - /// None => (), + /// if let Some(x) = map.get_mut(&1) { + /// *x = "b"; /// } /// assert_eq!(map[&1], "b"); /// ``` From 9e2598348f1f16367dced2e01f7981a9b7c084aa Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Sat, 18 Apr 2015 11:55:40 -0400 Subject: [PATCH 15/19] Indicate keywords are code-like in Fuse::reset_fuse doc comment --- src/libcore/iter.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index 7a955e2e70ad7..04178f65463e6 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -2246,8 +2246,9 @@ impl RandomAccessIterator for Fuse where I: RandomAccessIterator { impl ExactSizeIterator for Fuse where I: ExactSizeIterator {} impl Fuse { - /// Resets the fuse such that the next call to .next() or .next_back() will - /// call the underlying iterator again even if it previously returned None. + /// Resets the `Fuse` such that the next call to `.next()` or + /// `.next_back()` will call the underlying iterator again even if it + /// previously returned `None`. #[inline] #[unstable(feature = "core", reason = "seems marginal")] pub fn reset_fuse(&mut self) { From 007060ba07f25cef39dcc792eeae1a9d36fdf368 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Sat, 18 Apr 2015 17:36:41 +0200 Subject: [PATCH 16/19] doc: improve/fix 'let' FAQ --- src/doc/complement-design-faq.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/doc/complement-design-faq.md b/src/doc/complement-design-faq.md index 0f2c37a5abf83..56a19769647a1 100644 --- a/src/doc/complement-design-faq.md +++ b/src/doc/complement-design-faq.md @@ -165,12 +165,13 @@ particularly easy to read. ## Why is `let` used to introduce variables? -We don't use the term "variable", instead, we use "variable bindings". The -simplest way for binding is the `let` syntax, other ways including `if let`, -`while let` and `match`. Bindings also exist in function arguments positions. +Instead of the term "variable", we use "variable bindings". The +simplest way for creating a binding is by using the `let` syntax. +Other ways include `if let`, `while let`, and `match`. Bindings also +exist in function argument positions. Bindings always happen in pattern matching positions, and it's also Rust's way -to declare mutability. One can also redeclare mutability of a binding in +to declare mutability. One can also re-declare mutability of a binding in pattern matching. This is useful to avoid unnecessary `mut` annotations. An interesting historical note is that Rust comes, syntactically, most closely from ML, which also uses `let` to introduce bindings. From f19a12d6a2fe40b243bfddaf339858dee62dc949 Mon Sep 17 00:00:00 2001 From: Florian Hartwig Date: Thu, 16 Apr 2015 22:12:13 +0200 Subject: [PATCH 17/19] Fix broken links in the docs --- src/doc/complement-design-faq.md | 4 ++-- src/doc/trpl/closures.md | 6 +++--- src/libcore/raw.rs | 4 ++-- src/libcore/result.rs | 4 ++-- src/librustc/plugin/mod.rs | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/doc/complement-design-faq.md b/src/doc/complement-design-faq.md index 56a19769647a1..952416ac160e1 100644 --- a/src/doc/complement-design-faq.md +++ b/src/doc/complement-design-faq.md @@ -56,7 +56,7 @@ Types which are [`Sync`][sync] are thread-safe when multiple shared references to them are used concurrently. Types which are not `Sync` are not thread-safe, and thus when used in a global require unsafe code to use. -[sync]: core/kinds/trait.Sync.html +[sync]: core/marker/trait.Sync.html ### If mutable static items that implement `Sync` are safe, why is taking &mut SHARABLE unsafe? @@ -139,7 +139,7 @@ and explicitly calling the `clone` method. Making user-defined copy operators explicit surfaces the underlying complexity, forcing the developer to opt-in to potentially expensive operations. -[copy]: core/kinds/trait.Copy.html +[copy]: core/marker/trait.Copy.html [clone]: core/clone/trait.Clone.html ## No move constructors diff --git a/src/doc/trpl/closures.md b/src/doc/trpl/closures.md index e63331e5206bf..e3de8eb30be91 100644 --- a/src/doc/trpl/closures.md +++ b/src/doc/trpl/closures.md @@ -205,11 +205,11 @@ you tons of control over what your code does, and closures are no different. Rust's implementation of closures is a bit different than other languages. They are effectively syntax sugar for traits. You'll want to make sure to have read -the [traits chapter][traits] before this one, as well as the chapter on [static -and dynamic dispatch][dispatch], which talks about trait objects. +the [traits chapter][traits] before this one, as well as the chapter on [trait +objects][trait-objects]. [traits]: traits.html -[dispatch]: static-and-dynamic-dispatch.html +[trait-objects]: trait-objects.html Got all that? Good. diff --git a/src/libcore/raw.rs b/src/libcore/raw.rs index ded52ff07785e..685b3e5c546dd 100644 --- a/src/libcore/raw.rs +++ b/src/libcore/raw.rs @@ -71,11 +71,11 @@ impl Clone for Slice { /// The representation of a trait object like `&SomeTrait`. /// /// This struct has the same layout as types like `&SomeTrait` and -/// `Box`. The [Static and Dynamic Dispatch chapter of the +/// `Box`. The [Trait Objects chapter of the /// Book][moreinfo] contains more details about the precise nature of /// these internals. /// -/// [moreinfo]: ../../book/static-and-dynamic-dispatch.html#representation +/// [moreinfo]: ../../book/trait-objects.html#representation /// /// `TraitObject` is guaranteed to match layouts, but it is not the /// type of trait objects (e.g. the fields are not directly accessible diff --git a/src/libcore/result.rs b/src/libcore/result.rs index 919f8d9c73a62..e909946ece402 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -86,12 +86,12 @@ //! useful value. //! //! Consider the `write_all` method defined for I/O types -//! by the [`Write`](../io/trait.Write.html) trait: +//! by the [`Write`](../../std/io/trait.Write.html) trait: //! //! ``` //! use std::io; //! -//! trait Writer { +//! trait Write { //! fn write_all(&mut self, bytes: &[u8]) -> Result<(), io::Error>; //! } //! ``` diff --git a/src/librustc/plugin/mod.rs b/src/librustc/plugin/mod.rs index 3162c4fc57023..4a85e1893f0a1 100644 --- a/src/librustc/plugin/mod.rs +++ b/src/librustc/plugin/mod.rs @@ -47,7 +47,7 @@ //! #![plugin(myplugin)] //! ``` //! -//! See the [Plugins Chapter](../../book/plugins.html) of the book +//! See the [Plugins Chapter](../../book/compiler-plugins.html) of the book //! for more examples. pub use self::registry::Registry; From 01db977099ff522af286405b8e7ffd2af137b887 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Thu, 16 Apr 2015 11:53:17 -0400 Subject: [PATCH 18/19] Indicate None is code-like in doc comments --- src/libcore/iter.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index 04178f65463e6..233ed01811930 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -179,8 +179,8 @@ pub trait Iterator { /// Creates an iterator that iterates over both this and the specified /// iterators simultaneously, yielding the two elements as pairs. When - /// either iterator returns None, all further invocations of next() will - /// return None. + /// either iterator returns `None`, all further invocations of next() will + /// return `None`. /// /// # Examples /// @@ -254,7 +254,7 @@ pub trait Iterator { } /// Creates an iterator that both filters and maps elements. - /// If the specified function returns None, the element is skipped. + /// If the specified function returns `None`, the element is skipped. /// Otherwise the option is unwrapped and the new value is yielded. /// /// # Examples @@ -403,7 +403,7 @@ pub trait Iterator { /// Creates a new iterator that behaves in a similar fashion to fold. /// There is a state which is passed between each iteration and can be /// mutated as necessary. The yielded values from the closure are yielded - /// from the Scan instance when not None. + /// from the Scan instance when not `None`. /// /// # Examples /// @@ -701,7 +701,7 @@ pub trait Iterator { /// Returns the index of the last element satisfying the specified predicate /// - /// If no element matches, None is returned. + /// If no element matches, `None` is returned. /// /// Does not consume the iterator *before* the first found element. /// From b43138bc88fe5fc132dd6f241515c61a7b624af9 Mon Sep 17 00:00:00 2001 From: Aram Visser Date: Thu, 16 Apr 2015 19:21:11 +0700 Subject: [PATCH 19/19] Fixed typo in hash_map::Entry documentation --- src/libstd/collections/hash/map.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index f9eb21e89aadf..16b2c45bd8dc6 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -1463,7 +1463,6 @@ impl<'a, K, V> ExactSizeIterator for Drain<'a, K, V> { } impl<'a, K, V> Entry<'a, K, V> { - /// Returns a mutable reference to the entry if occupied, or the VacantEntry if vacant. #[unstable(feature = "std_misc", reason = "will soon be replaced by or_insert")] #[deprecated(since = "1.0",